Repository: vanhbakaa/moonbix-bot
Branch: main
Commit: 49516e761e57
Files: 29
Total size: 103.2 KB
Directory structure:
gitextract_smur5s11/
├── .env-example
├── .gitignore
├── LICENSE
├── README.md
├── bot/
│ ├── __init__.py
│ ├── config/
│ │ ├── __init__.py
│ │ ├── config.py
│ │ └── proxies.txt
│ ├── core/
│ │ ├── __init__.py
│ │ ├── agents.py
│ │ ├── headers.py
│ │ ├── query.py
│ │ ├── registrator.py
│ │ ├── solver/
│ │ │ ├── captcha/
│ │ │ │ ├── events.cp311-win_amd64.pyd
│ │ │ │ ├── payload.cp311-win_amd64.pyd
│ │ │ │ └── utils.cp311-win_amd64.pyd
│ │ │ ├── captcha_solver.cp311-win_amd64.pyd
│ │ │ └── classify/
│ │ │ ├── classifier.cp311-win_amd64.pyd
│ │ │ └── image.py
│ │ └── tapper.py
│ ├── exceptions/
│ │ └── __init__.py
│ └── utils/
│ ├── __init__.py
│ ├── launcher.py
│ └── logger.py
├── main.py
├── requirements.txt
├── run.bat
├── run.sh
└── version
================================================
FILE CONTENTS
================================================
================================================
FILE: .env-example
================================================
API_ID=
API_HASH=
REF_LINK=
AUTO_TASK=
AUTO_PLAY_GAME=
DELAY_EACH_ACCOUNT=
MORE_ACCURATE_CAPTCHA_SOLVER=
USE_PROXY_FROM_FILE=
================================================
FILE: .gitignore
================================================
.env
sessions
data.txt
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
## Recommendation before use
# Join the bot [here](https://t.me/Binance_Moonbix_bot/start?startApp=ref_6624523270&startapp=ref_6624523270&utm_medium=web_share_copy)
> [!WARNING]
> ⚠️ I do my best to avoid detection of bots, but using bots is forbidden in all airdrops. i cannot guarantee that you will not be detected as a bot. Use at your own risk. I am not responsible for any consequences of using this software.
# 🔥🔥 MUST USE PYTHON 3.11.5 (CAPTCHA VERSION ISN'T WORK ON TERMUX)🔥🔥
## Features
| Feature | Supported |
|---------------------------------------------------------------|:----------------:|
| Multithreading | ✅ |
| Proxy binding to session | ✅ |
| Auto ref | ✅ |
| Auto checkin | ✅ |
| Auto play game | ✅ |
| Auto solve captcha | ✅ |
| Support for pyrogram .session | ✅ |
Auto get maxium points each game | ✅ |
## [Settings](https://github.com/vanhbakaa/moonbix-bot/blob/main/.env-example)
| Settings | Description |
|----------------------------|:-------------------------------------------------------------------------------------------------------------:|
| **API_ID / API_HASH** | Platform data from which to run the Telegram session (default - android) |
| **REF_LINK** | Put your ref link here (default: my ref link) |
| **AUTO_TASK** | Auto do task (default: True) |
| **AUTO_PLAY_GAME** | AUTO PLAY GAME (default: True) |
| **MORE_ACCURATE_CAPTCHA_SOLVER** | Option to use more accurate solver (it will slower) (default: False) |
| **DELAY_EACH_ACCOUNT** | SLEEP between each account (default: [15,25]) |
| **USE_PROXY_FROM_FILE** | Whether to use a proxy from the bot/config/proxies.txt file (True / False) |
## Quick Start 📚
To install libraries and run bot - open run.bat on Windows
## Prerequisites
Before you begin, make sure you have the following installed:
- [Python](https://www.python.org/downloads/) **version 3.11.5**
## Obtaining API Keys
1. Go to my.telegram.org and log in using your phone number.
2. Select "API development tools" and fill out the form to register a new application.
3. Record the API_ID and API_HASH provided after registering your application in the .env file.
## Installation
You can download the [**repository**](https://github.com/vanhbakaa/Kaia-bot/) by cloning it to your system and installing the necessary dependencies:
```shell
git clone https://github.com/vanhbakaa/moonbix-bot.git
cd moonbix-bot
```
Then you can do automatic installation by typing:
Windows:
```shell
run.bat
```
Linux:
```shell
run.sh
```
# Linux manual installation
```shell
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
cp .env-example .env
nano .env # Here you must specify your API_ID and API_HASH, the rest is taken by default
python3 main.py
```
You can also use arguments for quick start, for example:
```shell
~/moonbix-bot >>> python3 main.py --action (1/2)
# Or
~/moonbix-bot >>> python3 main.py -a (1/2)
# 1 - Run clicker
# 2 - Creates a session
```
# Windows manual installation
```shell
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
copy .env-example .env
# Here you must specify your API_ID and API_HASH, the rest is taken by default
python main.py
```
You can also use arguments for quick start, for example:
```shell
~/moonbix-bot >>> python main.py --action (1/2)
# Or
~/moonbix-bot >>> python main.py -a (1/2)
# 1 - Run clicker
# 2 - Creates a session
```
# Termux manual installation
```
> pkg update && pkg upgrade -y
> pkg install python rust git -y
> git clone https://github.com/vanhbakaa/moonbix-bot.git
> cd moonbix-bot
> pip install -r requirements.txt
> python main.py
```
You can also use arguments for quick start, for example:
```termux
~/moonbix-bot > python main.py --action (1/2)
# Or
~/moonbix-bot > python main.py -a (1/2)
# 1 - Run clicker
# 2 - Creates a session
```
# Support This Project
If you'd like to support the development of this project, please consider making a donation. Every little bit helps!
👉 **[Click here to view donation options](https://github.com/vanhbakaa/Donation/blob/main/README.md)** 👈
Your support allows us to keep improving the project and bring more features!
Thank you for your generosity! 🙌
### Contacts
For support or questions, you can contact me [](https://t.me/airdrop_tool_vanh)
================================================
FILE: bot/__init__.py
================================================
__version__ = '1.0'
================================================
FILE: bot/config/__init__.py
================================================
from .config import settings
================================================
FILE: bot/config/config.py
================================================
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_ignore_empty=True)
API_ID: int
API_HASH: str
REF_LINK: str = "https://t.me/Binance_Moonbix_bot/start?startApp=ref_6624523270&startapp=ref_6624523270&utm_medium=web_share_copy"
AUTO_TASK: bool = True
AUTO_PLAY_GAME: bool = True
DELAY_EACH_ACCOUNT: list[int] = [60, 120]
MORE_ACCURATE_CAPTCHA_SOLVER: bool = False
USE_PROXY_FROM_FILE: bool = False
settings = Settings()
================================================
FILE: bot/config/proxies.txt
================================================
http://38.154.227.167:5868:vanhbaka:Vanhdayyyy
http://45.127.248.127:5128:vanhbaka:Vanhdayyyy
http://207.244.217.165:6712:vanhbaka:Vanhdayyyy
================================================
FILE: bot/core/__init__.py
================================================
__version__ = '1.0'
================================================
FILE: bot/core/agents.py
================================================
import random
def generate_random_user_agent(device_type='android', browser_type='chrome'):
chrome_versions = list(range(110, 127))
firefox_versions = list(range(90, 100))
if browser_type == 'chrome':
major_version = random.choice(chrome_versions)
minor_version = random.randint(0, 9)
build_version = random.randint(1000, 9999)
patch_version = random.randint(0, 99)
browser_version = f"{major_version}.{minor_version}.{build_version}.{patch_version}"
elif browser_type == 'firefox':
browser_version = random.choice(firefox_versions)
if device_type == 'android':
android_versions = ['10.0', '11.0', '12.0', '13.0']
android_device = random.choice([
'SM-G960F', 'Pixel 5', 'SM-A505F', 'Pixel 4a', 'Pixel 6 Pro', 'SM-N975F',
'SM-G973F', 'Pixel 3', 'SM-G980F', 'Pixel 5a', 'SM-G998B', 'Pixel 4',
'SM-G991B', 'SM-G996B', 'SM-F711B', 'SM-F916B', 'SM-G781B', 'SM-N986B',
'SM-N981B', 'Pixel 2', 'Pixel 2 XL', 'Pixel 3 XL', 'Pixel 4 XL',
'Pixel 5 XL', 'Pixel 6', 'Pixel 6 XL', 'Pixel 6a', 'Pixel 7', 'Pixel 7 Pro',
'OnePlus 8', 'OnePlus 8 Pro', 'OnePlus 9', 'OnePlus 9 Pro', 'OnePlus Nord', 'OnePlus Nord 2',
'OnePlus Nord CE', 'OnePlus 10', 'OnePlus 10 Pro', 'OnePlus 10T', 'OnePlus 10T Pro',
'Xiaomi Mi 9', 'Xiaomi Mi 10', 'Xiaomi Mi 11', 'Xiaomi Redmi Note 8', 'Xiaomi Redmi Note 9',
'Huawei P30', 'Huawei P40', 'Huawei Mate 30', 'Huawei Mate 40', 'Sony Xperia 1',
'Sony Xperia 5', 'LG G8', 'LG V50', 'LG V60', 'Nokia 8.3', 'Nokia 9 PureView'
])
android_version = random.choice(android_versions)
if browser_type == 'chrome':
return (f"Mozilla/5.0 (Linux; Android {android_version}; {android_device}) AppleWebKit/537.36 "
f"(KHTML, like Gecko) Chrome/{browser_version} Mobile Safari/537.36")
elif browser_type == 'firefox':
return (f"Mozilla/5.0 (Android {android_version}; Mobile; rv:{browser_version}.0) "
f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")
elif device_type == 'ios':
ios_versions = ['13.0', '14.0', '15.0', '16.0']
ios_version = random.choice(ios_versions)
if browser_type == 'chrome':
return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
f"AppleWebKit/537.36 (KHTML, like Gecko) CriOS/{browser_version} Mobile/15E148 Safari/604.1")
elif browser_type == 'firefox':
return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
f"AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/{browser_version}.0 Mobile/15E148 Safari/605.1.15")
elif device_type == 'windows':
windows_versions = ['10.0', '11.0']
windows_version = random.choice(windows_versions)
if browser_type == 'chrome':
return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
f"Chrome/{browser_version} Safari/537.36")
elif browser_type == 'firefox':
return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64; rv:{browser_version}.0) "
f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")
elif device_type == 'ubuntu':
if browser_type == 'chrome':
return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) AppleWebKit/537.36 (KHTML, like Gecko) "
f"Chrome/{browser_version} Safari/537.36")
elif browser_type == 'firefox':
return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{browser_version}.0) Gecko/{browser_version}.0 "
f"Firefox/{browser_version}.0")
return None
================================================
FILE: bot/core/headers.py
================================================
headers = {
'Accept': '*/*',
'Accept-Language': 'en-US',
"Bnc-Uuid": "",
'Clienttype': "web",
'Content-Type': 'application/json',
'Csrftoken': 'd41d8cd98f00b204e9800998ecf8427e',
'Device-Info': "",
"Priority": "u=1, i",
"Fvideo-Id": "33bda003f0aea1fa919ee400b6e9f40775ff584a",
"Fvideo-Token": "",
"Lang": "en",
'Origin': 'https://www.binance.com',
'Referer': 'https://www.binance.com/en/game/tg/moon-bix',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36',
"X-Growth-Token": ""
}
================================================
FILE: bot/core/query.py
================================================
import asyncio
import json
import random
import traceback
from itertools import cycle
from time import time
from urllib.parse import unquote, quote
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import base64
import aiohttp
from aiocfscrape import CloudflareScraper
from aiohttp_proxy import ProxyConnector
from better_proxy import Proxy
from pyrogram import Client
from pyrogram.errors import Unauthorized, UserDeactivated, AuthKeyUnregistered, FloodWait
from pyrogram.raw.types import InputBotAppShortName
from pyrogram.raw.functions.messages import RequestAppWebView
from soupsieve.util import lower
from bot.core.agents import generate_random_user_agent
from bot.config import settings
import cloudscraper
from math import sqrt
from bot.utils import logger
from bot.exceptions import InvalidSession
from .headers import headers
from random import randint, choices, choice, uniform
import secrets
import uuid
from faker import Faker
import string
fake = Faker()
min_length = 256
max_length = 1024
def base64_encode(data):
return base64.b64encode(data).decode('utf-8')
class Tapper:
def __init__(self, query: str, accname: str):
self.query = query
self.session_name = accname
self.first_name = ''
self.last_name = ''
temp_query = unquote(query)
self.user_id = temp_query.split('"id":')[1].split(',"first_name"')[0]
# print(self.user_id)
self.user = ''
self.auth_token = ""
self.last_claim = None
self.last_checkin = None
self.balace = 0
self.access_token = None
self.game_response = None
self.game = None
self.rs = 1000
self.curr_time = None
def random_fingerprint(self, lengths=32):
return ''.join(choices('0123456789abcdef', k=lengths))
def generate_Fvideo_token(self, length):
characters = string.ascii_letters + string.digits + "+/"
digits = string.digits
characters1 = string.ascii_letters + digits
random_string = ''.join(choice(characters) for _ in range(length - 3))
random_string += '='
random_string += choice(digits)
random_string += choice(characters1)
return random_string
fake = Faker()
def get_random_resolution(self):
width = randint(720, 1920)
height = randint(720, 1080)
return f"{width},{height}"
def get_random_timezone(self):
timezones = [
"GMT+07:00", "GMT+05:30", "GMT-08:00", "GMT+00:00", "GMT+03:00"
]
return choice(timezones)
def get_random_timezone_offset(self, timezone):
# Extract the offset from the timezone format "GMT+07:00"
sign = 1 if "+" in timezone else -1
hours = int(timezone.split("GMT")[1].split(":")[0])
return sign * hours * 60
def get_random_plugins(self):
plugins = [
"PDF Viewer,Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,WebKit built-in PDF",
"Flash,Java,Silverlight,QuickTime",
"Chrome PDF Viewer,Widevine Content Decryption Module",
]
return choice(plugins)
def get_random_canvas_code(self):
return ''.join(choices(lower(string.hexdigits), k=8))
def get_random_fingerprint(self):
return ''.join(choices(lower(string.hexdigits), k=32))
def generate_random_data(self, user_agent):
timezone = self.get_random_timezone()
sol = self.get_random_resolution()
data = {
"screen_resolution": sol,
"available_screen_resolution": sol,
"system_version": fake.random_element(["Windows 10", "Windows 11", "Ubuntu 20.04"]),
"brand_model": fake.random_element(["unknown", "Dell XPS 13", "HP Spectre"]),
"system_lang": "en-EN",
"timezone": timezone,
"timezoneOffset": self.get_random_timezone_offset(timezone),
"user_agent": user_agent,
"list_plugin": self.get_random_plugins(),
"canvas_code": self.get_random_canvas_code(),
"webgl_vendor": fake.company(),
"webgl_renderer": f"ANGLE ({fake.company()}, {fake.company()} Graphics)",
"audio": str(uniform(100, 130)),
"platform": fake.random_element(["Win32", "Win64"]),
"web_timezone": fake.timezone(),
"device_name": f"{fake.user_agent()} ({fake.random_element(['Windows'])})",
"fingerprint": self.get_random_fingerprint(),
"device_id": "",
"related_device_ids": ""
}
return data
async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy):
try:
response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5), ssl=False)
ip = (await response.json()).get('origin')
logger.info(f"{self.session_name} | Proxy IP: {ip}")
return True
except Exception as error:
logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
return False
def setup_session(self, session: cloudscraper.CloudScraper):
payload = {
"queryString": self.auth_token,
"socialType": "telegram"
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/third-party/access/accessToken",
headers=headers, json=payload)
data_ = response.json()
if data_['code'] == '000000':
logger.success(f"{self.session_name} | <green>Get access token sucessfully</green>")
self.access_token = data_['data']['accessToken']
else:
logger.warning(f"{self.session_name} | <red>Get access token failed: {data_}</red>")
def random_data_type(self, type, end_time, item_size, item_pts, pos_y: float):
# I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !
# end_time = int(end_time)
if type == 1:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
hook_hit_y = "{:.3f}".format(pos_y)
multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
hook_shot_angle = "{:.3f}".format(cal_angle)
item_type = 1
item_s = item_size
point = randint(1, 200)
elif type == 2:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
# hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
hook_hit_y = "{:.3f}".format(pos_y)
multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
hook_shot_angle = "{:.3f}".format(cal_angle)
item_type = 2
item_s = item_size
point = int(item_size) + int(item_pts)
elif type == 0:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
# hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
hook_hit_y = "{:.3f}".format(pos_y)
multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
hook_shot_angle = "{:.3f}".format(cal_angle)
item_type = 0
item_s = item_size
point = randint(1, 200)
else:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
hook_hit_x = 0
hook_hit_y = 0
item_type = randint(0, 2)
item_s = randint(1, 100)
point = randint(1, 200)
# 1727080937255|272.705|208.070|-0.944|0|0|2|38|12;1727080938339|224.985|241.018|-0.432|249.685|294.600|1|70|182;1727080941172|124.175|241.530|0.420|0|0|2|57|186;1727080943373|77.580|210.808|0.910|0|0|2|7|140;1727080944891|181.929|250.277|-0.066|189.091|359.041|2|60|90;1727080948123|269.666|211.426|-0.902|0|0|2|92|11;1727080949024|279.568|199.250|-1.047|0|0|2|60|34;1727080950908|162.174|250.020|0.096|144.951|428.190|0|30|191;1727080953975|78.758|212.055|0.895|0|0|0|1|151;1727080955243|133.916|244.791|0.334|103.100|333.596|1|30|15;1727080957193|278.835|200.291|-1.035|0|0|1|5|150;1727080959444|209.788|245.932|-0.298|303.593|550.828|1|70|72;1727080965178|87.635|220.354|0.786|0|0|1|85|73;1727080967129|168.297|250.390|0.046|156.376|509.116|1|50|110;1727080971647|188.297|249.779|-0.118|209.403|427.530|1|30|30;1727080974548|145.269|252.269|0.237|105.591|416.545|1|30|92;1727080978299|172.753|252.036|0.010|168.866|661.017|1|50|13
data = f"{pick_time}|{hook_pos_x}|{hook_pos_y}|{hook_shot_angle}|{hook_hit_x}|{hook_hit_y}|{item_type}|{item_s}|{point}"
return data
def encrypt(self, text, key):
iv = get_random_bytes(12)
iv_base64 = base64_encode(iv)
# print(iv_base64[:16].encode('utf-8'))
cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv_base64[:16].encode('utf-8'))
ciphertext = cipher.encrypt(pad(text.encode('utf-8'), AES.block_size))
ciphertext_base64 = base64_encode(ciphertext)
return iv_base64 + ciphertext_base64
def get_game_data(self):
# I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !
try:
end_time = int((time() + 45) * 1000)
# print(end_time)
random_pick_time = randint(8, 15)
total_obj = 0
key_for_game = self.game_response['data']['gameTag']
obj_type = {
"coin": {},
"trap": {},
"bonus": ""
}
for obj in self.game_response['data']['cryptoMinerConfig']['itemSettingList']:
total_obj += obj['quantity']
if obj['type'] == "BONUS":
obj_type['bonus'] = f"{obj['rewardValueList'][0]},{obj['size']}"
else:
for reward in obj['rewardValueList']:
if int(reward) > 0:
obj_type['coin'].update({reward: f"{obj['size']},{obj['quantity']}"})
else:
obj_type['trap'].update({abs(int(reward)): f"{obj['size']},{obj['quantity']}"})
limit = min(total_obj, random_pick_time)
random_pick_sth_times = randint(1, limit)
picked_bonus = False
picked = 0
logger.info(f"{self.session_name} | Playing game!")
game_data_payload = []
score = 0
# print(obj_type)
pos_y = []
for i in range(random_pick_sth_times + 5):
pos_y.append(uniform(250, 550))
sorted_pos_y = sorted(pos_y)
for i in range(1, len(sorted_pos_y)):
if sorted_pos_y[i] - sorted_pos_y[i - 1] < 40:
sorted_pos_y[i] += randint(40, 55)
Total_tap = 0
while end_time > self.curr_time and picked < random_pick_sth_times:
self.rs = randint(2500, 4000)
random_reward = randint(1, 100)
if random_reward <= 20:
if len(list(obj_type['trap'].keys())) > 0:
picked += 1
reward_d = choice(list(obj_type['trap'].keys()))
quantity = obj_type['trap'][reward_d].split(',')[1]
item_size = obj_type['trap'][reward_d].split(',')[0]
if int(quantity) > 0:
data_ = self.random_data_type(end_time=end_time,
type=0,
item_size=int(item_size),
item_pts=0,
pos_y=sorted_pos_y[Total_tap])
if data_ is not None:
Total_tap += 1
score = max(0, score - int(reward_d))
game_data_payload.append(data_)
if int(quantity) - 1 > 0:
obj_type['trap'].update({reward_d: f"{item_size},{int(quantity) - 1}"})
else:
obj_type["trap"].pop(reward_d)
else:
break
elif random_reward > 20 and random_reward <= 70:
if len(list(obj_type['coin'].keys())) > 0:
picked += 1
reward_d = choice(list(obj_type['coin'].keys()))
quantity = obj_type['coin'][reward_d].split(',')[1]
item_size = obj_type['coin'][reward_d].split(',')[0]
if int(quantity) > 0:
data_ = self.random_data_type(end_time=end_time,
type=1,
item_size=item_size,
item_pts=0,
pos_y=sorted_pos_y[Total_tap])
if data_ is not None:
Total_tap += 1
score += int(reward_d)
game_data_payload.append(data_)
if int(quantity) - 1 > 0:
obj_type['coin'].update({reward_d: f"{item_size},{int(quantity) - 1}"})
else:
obj_type["coin"].pop(reward_d)
else:
break
elif random_reward > 70 and random_reward <= 100 and picked_bonus is False:
picked += 1
size = obj_type['bonus'].split(',')[1]
pts = obj_type['bonus'].split(',')[0]
data_ = self.random_data_type(end_time=end_time,
type=2,
item_size=size,
item_pts=pts,
pos_y=sorted_pos_y[Total_tap])
if data_ is not None:
Total_tap += 1
picked_bonus = True
score += int(pts)
game_data_payload.append(data_)
self.curr_time += self.rs
if len(game_data_payload) > 0:
data_pl = ';'.join(game_data_payload)
# print(data_pl)
game_payload = self.encrypt(data_pl, key_for_game)
self.game = {
"payload": game_payload,
"log": score,
"debug": data_pl
}
# print(self.game)
return True
else:
logger.warning(f"{self.session_name} | <yellow>Failed to play game, reason: Time out</yellow>")
return False
except Exception as error:
traceback.print_exc()
logger.error(f"{self.session_name} | <red>Unknown error while trying to get game data: {str(error)}</red>")
return False
def setup_account(self, session: cloudscraper.CloudScraper):
ref_id = settings.REF_LINK.split("=")[1].split('&')[0].split('_')[1]
payload = {
"agentId": str(ref_id),
"resourceId": 2056
}
res = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/referral",
headers=headers,
json=payload)
json_d = res.json()
if json_d['success']:
res = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/participated",
headers=headers, json=payload)
json_d = res.json()
if json_d['success']:
logger.success(f"{self.session_name} | <green>Successfully set up account !</green>")
login_task = {
"resourceId": 2057
}
complete = self.complete_task(session, login_task)
if complete == "done":
logger.success(f"{self.session_name} | <green>Successfully checkin for the first time !</green>")
else:
logger.warning(
f"{self.session_name} | <yellow>Unknown error while tryng to init account: {json_d}</yellow>")
async def get_user_info(self, session: cloudscraper.CloudScraper):
payload = {
"resourceId": 2056
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
headers=headers, json=payload)
data_ = response.json()
# print(data_)
if data_['code'] == '000000':
# print(data_)
data__ = data_['data']
if data__['participated'] is False:
logger.info(f"{self.session_name} | Attempt to set up account...")
self.setup_account(session)
await asyncio.sleep(uniform(3, 5))
await self.get_user_info(session)
else:
logger.info(f"{self.session_name} | <cyan>Logged in</cyan>")
logger.info(
f"{self.session_name} | Total point: <yellow>{data__['metaInfo']['totalGrade']}</yellow> | <white>Risk Passed: <red>{data__['riskPassed']}</red> | Qualified: <red>{data__['qualified']}</red></white>")
else:
logger.warning(f"{self.session_name} | <red>Get user data failed: {data_}</red>")
def get_user_info1(self, session: cloudscraper.CloudScraper):
payload = {
"resourceId": 2056
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
headers=headers, json=payload)
data_ = response.json()
if data_['code'] == '000000':
# print(data_)
data__ = data_['data']
return data__
else:
logger.warning(f"{self.session_name} | <red>Get ticket data failed: {data_}</red>")
def get_task_list(self, session: cloudscraper.CloudScraper):
payload = {
"resourceId": 2056
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/list",
headers=headers, json=payload)
data_ = response.json()
# print(data_)
if data_['code'] == '000000':
task_list = data_['data']['data'][0]['taskList']['data'] # bruh what are they doing ????
tasks = []
for task in task_list:
# print(task)
if task['type'] == "THIRD_PARTY_BIND":
continue
elif task['status'] == "COMPLETED":
continue
elif task['status'] == "IN_PROGRESS":
tasks.append(task)
return tasks
else:
logger.warning(f"{self.session_name} | <red>Get tasks list failed: {data_}</red>")
return None
def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
task_ids = [task['resourceId']]
payload = {
"referralCode": "null",
"resourceIdList": task_ids
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/complete",
headers=headers, json=payload)
data_ = response.json()
# print(data_)
if data_['success']:
return "done"
else:
return data_['messageDetail']
def complete_game(self, session: cloudscraper.CloudScraper):
string_payload = self.game['payload']
payload = {
"log": self.game['log'],
"payload": string_payload,
"resourceId": 2056
}
# print(payload)
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/complete",
headers=headers, json=payload)
data_ = response.json()
if data_['success']:
logger.success(
f"{self.session_name} | <green>Sucessfully earned: <yellow>{self.game['log']}</yellow> from game !</green>")
else:
logger.warning(
f"{self.session_name} | <yellow>Failed to complete game | {self.game['log']}: {data_}</yellow>")
def auto_update_ticket(self, session: cloudscraper.CloudScraper):
ticket_data = self.get_user_info1(session)
return ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']
async def play_game(self, session: cloudscraper.CloudScraper):
ticket_data = self.get_user_info1(session)
if ticket_data['metaInfo']['totalAttempts'] == ticket_data['metaInfo']['consumedAttempts']:
logger.warning(f"{self.session_name} | No Attempt left to play game...")
return
attempt_left = ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']
logger.info(f"{self.session_name} | Starting to play game...")
while attempt_left > 0:
# await asyncio.sleep(1000)
logger.info(f"{self.session_name} | Attempts left: <cyan>{attempt_left}</cyan>")
payload = {
"resourceId": 2056
}
headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
# print(headers)
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
headers=headers, json=payload)
if response.status_code == 200:
data_ = response.json()
# print(data_)
if 'sessionId' in data_['data']:
# print("ok")
sessionId = data_['data']['sessionId']
captcha_data = f"bizId=tg_mini_game_play&sv=20220812&lang=en&securityCheckResponseValidateId={data_['data']['securityCheckValidateId']}&clientType=web"
captcha_header = {
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"content-type": "text/plain; charset=UTF-8",
"bnc-uuid": "xxx",
"captcha-sdk-version": "1.0.0",
"clienttype": "web",
"device-info": headers['Device-Info'],
"fvideo-id": "xxx",
"origin": "https://www.binance.com",
"referer": "https://www.binance.com/",
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
"user-agent": headers["User-Agent"],
"x-captcha-se": "true"
}
cap_res = session.post("https://api.commonservice.io/gateway-api/v1/public/antibot/getCaptcha",
headers=captcha_header, data=captcha_data)
if cap_res.status_code == 200:
# print(cap_res.text)
captcha_data_ = cap_res.json()['data']
cap_type = captcha_data_['captchaType']
bizId = captcha_data
sig = captcha_data_['sig']
salt = captcha_data_['salt']
tag = captcha_data_['tag']
path2 = captcha_data_['path2']
ek = captcha_data_['ek']
logger.info(f"{self.session_name} | Attempt to solve captcha ({tag})...")
captcha_data = {
"sig": sig,
"salt": salt,
"path2": path2,
"ek": ek,
"captchaType": cap_type,
"tag": tag
}
# dat = {
# "mode": "VANHBAKA",
# "bizId": bizId,
# "captchaData": {
# "sig": sig,
# "salt": salt,
# "path2": path2,
# "ek": ek,
# "captchaType": cap_type,
# "tag": tag
# }
# }
# head = {
# "user_id": self.user_id
# }
#
# solve = session.post("http://127.0.0.1:5000/captcha/solve", json=dat, headers=head)
# solve1 = solve.json()
# print(solve1)
# print(payload)
from bot.core.solver.captcha_solver import solve_captcha
solve = await solve_captcha(bizId, captcha_data)
# print(solve)
await asyncio.sleep(random.uniform(2,4))
if solve['ok']:
sol = solve['solution']
# print(sol)
vaild_captcha = f"{bizId}&data={sol['payload']}&s={sol['s']}&sig={sig}"
# print(vaild_captcha)
solver = session.post(
"https://api.commonservice.io/gateway-api/v1/public/antibot/validateCaptcha",
data=vaild_captcha, headers=captcha_header)
if solver.status_code == 200:
# print(solver.json())
captcha_token = solver.json()['data']['token']
if captcha_token == "":
logger.warning(
f"{self.session_name} | <yellow>Failed to solve captcha. Try again next round...</yellow>")
sleep_ = uniform(10, 15)
logger.info(f"{self.session_name} | Sleep {sleep_}s...")
await asyncio.sleep(sleep_)
continue
logger.success(f"{self.session_name} | <green>Solved captcha successfully | Solve time: <cyan>{solve['solveTime']}s</cyan></green>")
headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
start_game_header = headers.copy()
start_game_header['X-Captcha-Challenge'] = sig
start_game_header['X-Captcha-Session-Id'] = sessionId
start_game_header['X-Captcha-Token'] = captcha_token
payload = {
"resourceId": 2056
}
# print(start_game_header)
res_d = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
headers=start_game_header, json=payload)
data_ = res_d.json()
# print(data_)
attempt_left = self.auto_update_ticket(session)
if data_['success']:
logger.success(
f"{self.session_name} | <green>Game <cyan>{data_['data']['gameTag']}</cyan> started successful</green>")
self.game_response = data_
# print(data_)
sleep_ = uniform(45, 45.05)
self.curr_time = int((time() * 1000))
check = self.get_game_data()
if check:
logger.info(
f"{self.session_name} | Wait <white>{sleep_}s</white> to complete the game...")
await asyncio.sleep(sleep_)
self.complete_game(session)
else:
print(response.text)
logger.warning(f"Start game failed: {response.status_code}")
sleep_ = uniform(20, 25)
logger.info(f"{self.session_name} | Sleep {sleep_}s...")
await asyncio.sleep(sleep_)
async def run(self, proxy: str | None) -> None:
access_token_created_time = 0
proxy_conn = ProxyConnector().from_url(proxy) if proxy else None
headers["User-Agent"] = generate_random_user_agent(device_type='android', browser_type='chrome')
http_client = CloudflareScraper(headers=headers, connector=proxy_conn)
session = cloudscraper.create_scraper()
if proxy:
proxy_check = await self.check_proxy(http_client=http_client, proxy=proxy)
if proxy_check:
proxy_type = proxy.split(':')[0]
proxies = {
proxy_type: proxy
}
session.proxies.update(proxies)
logger.info(f"{self.session_name} | bind with proxy ip: {proxy}")
token_live_time = randint(28700, 28800)
while True:
try:
if time() - access_token_created_time >= token_live_time:
tg_web_data = self.query
self.auth_token = tg_web_data
data = self.generate_random_data(headers['User-Agent'])
json_data = json.dumps(data)
encoded_data = base64.b64encode(json_data.encode()).decode()
headers['Device-Info'] = encoded_data
# print(encoded_data)
fvideo_token = self.generate_Fvideo_token(196)
headers['X-Tg-User-Id'] = self.user_id
# print(self.user)
headers['Fvideo-Id'] = secrets.token_hex(20)
headers['Fvideo-Token'] = fvideo_token
headers['Bnc-Uuid'] = str(uuid.uuid4())
headers['Cookie'] = f"theme=dark; bnc-uuid={headers['Bnc-Uuid']};"
# print(fvideo_token)
self.setup_session(session)
access_token_created_time = time()
token_live_time = randint(3500, 3600)
if self.access_token:
headers['X-Growth-Token'] = self.access_token
await self.get_user_info(session)
if settings.AUTO_TASK:
task_list = self.get_task_list(session)
for task in task_list:
check = self.complete_task(session, task)
if check == "done":
logger.success(
f"{self.session_name} | <green>Successfully completed task <cyan>{task['type']}</cyan> | Reward: <yellow>{task['rewardList'][0]['amount']}</yellow></green>")
else:
logger.warning(
f"{self.session_name} | <light-yellow> Failed to complete task: {task['type']}, msg: {check}</light-yellow>")
await asyncio.sleep(uniform(3, 5))
if settings.AUTO_PLAY_GAME:
await self.play_game(session)
logger.info(f"<light-blue>==Completed {self.session_name}==</light-blue>")
session.close()
await http_client.close()
# session.close()
break
except InvalidSession as error:
raise error
except Exception as error:
traceback.print_exc()
logger.error(f"{self.session_name} | Unknown error: {error}")
await asyncio.sleep(delay=randint(60, 120))
async def run_tapper_no_thread_query(queryids, proxies):
proxies_cycle = cycle(proxies) if proxies else None
acc = "Account"
while True:
i = 0
for query in queryids:
try:
await Tapper(query=query, accname=f"{acc}-{i}").run(next(proxies_cycle) if proxies_cycle else None)
i += 1
except InvalidSession:
logger.error(f"{query} | Invalid Session")
sleep_ = randint(settings.DELAY_EACH_ACCOUNT[0], settings.DELAY_EACH_ACCOUNT[1])
logger.info(f"Sleep {sleep_}s...")
await asyncio.sleep(sleep_)
sleep_ = randint(1500, 2500)
logger.info(f"<red>Sleep {sleep_}s...</red>")
await asyncio.sleep(sleep_)
================================================
FILE: bot/core/registrator.py
================================================
from pyrogram import Client
from bot.config import settings
from bot.utils import logger
async def register_sessions() -> None:
API_ID = settings.API_ID
API_HASH = settings.API_HASH
if not API_ID or not API_HASH:
raise ValueError("API_ID and API_HASH not found in the .env file.")
session_name = input('\nEnter the session name (press Enter to exit): ')
if not session_name:
return None
session = Client(
name=session_name,
api_id=API_ID,
api_hash=API_HASH,
workdir="sessions/"
)
async with session:
user_data = await session.get_me()
logger.success(f'Session added successfully @{user_data.username} | {user_data.first_name} {user_data.last_name}')
================================================
FILE: bot/core/solver/classify/image.py
================================================
from PIL import Image
import requests
from io import BytesIO
async def process_image(url):
square_size = 110
try:
response = requests.get(url)
image = Image.open(BytesIO(response.content))
cropped_images = []
for row in range(3):
for col in range(3):
x_min = col * square_size
y_min = row * square_size
x_max = x_min + square_size
y_max = y_min + square_size
# Crop the image
cropped_image = image.crop((x_min, y_min, x_max, y_max))
cropped_images.append(cropped_image)
return cropped_images
except Exception as err:
return str(err)
================================================
FILE: bot/core/tapper.py
================================================
import asyncio
import json
import random
import traceback
from itertools import cycle
from time import time
from urllib.parse import unquote, quote
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import base64
import aiohttp
from aiocfscrape import CloudflareScraper
from aiohttp_proxy import ProxyConnector
from better_proxy import Proxy
from pyrogram import Client
from pyrogram.errors import Unauthorized, UserDeactivated, AuthKeyUnregistered, FloodWait
from pyrogram.raw.types import InputBotAppShortName
from pyrogram.raw.functions.messages import RequestAppWebView
from soupsieve.util import lower
from bot.core.agents import generate_random_user_agent
from bot.config import settings
import cloudscraper
from math import sqrt
from bot.utils import logger
from bot.exceptions import InvalidSession
from .headers import headers
from random import randint, choices, choice, uniform
import secrets
import uuid
from faker import Faker
import string
fake = Faker()
min_length = 256
max_length = 1024
def base64_encode(data):
return base64.b64encode(data).decode('utf-8')
class Tapper:
def __init__(self, tg_client: Client):
self.tg_client = tg_client
self.session_name = tg_client.name
self.first_name = ''
self.last_name = ''
self.user_id = ''
self.user = ''
self.auth_token = ""
self.last_claim = None
self.last_checkin = None
self.balace = 0
self.access_token = None
self.game_response = None
self.game = None
self.rs = 1000
self.curr_time = None
async def get_tg_web_data(self, proxy: str | None) -> str:
ref_param = settings.REF_LINK.split("=")[1].split('&')[0]
if proxy:
proxy = Proxy.from_str(proxy)
proxy_dict = dict(
scheme=proxy.protocol,
hostname=proxy.host,
port=proxy.port,
username=proxy.login,
password=proxy.password
)
else:
proxy_dict = None
self.tg_client.proxy = proxy_dict
try:
if not self.tg_client.is_connected:
try:
await self.tg_client.connect()
except (Unauthorized, UserDeactivated, AuthKeyUnregistered):
raise InvalidSession(self.session_name)
while True:
try:
peer = await self.tg_client.resolve_peer('Binance_Moonbix_bot')
break
except FloodWait as fl:
fls = fl.value
logger.warning(f"<light-yellow>{self.session_name}</light-yellow> | FloodWait {fl}")
logger.info(f"<light-yellow>{self.session_name}</light-yellow> | Sleep {fls}s")
await asyncio.sleep(fls + 3)
web_view = await self.tg_client.invoke(RequestAppWebView(
peer=peer,
app=InputBotAppShortName(bot_id=peer, short_name="start"),
platform='android',
write_allowed=True,
start_param=ref_param
))
auth_url = web_view.url
# print(auth_url)
tg_web_data1 = unquote(string=auth_url.split('tgWebAppData=')[1].split('&tgWebAppVersion')[0])
tg_web_data = unquote(
string=unquote(string=auth_url.split('tgWebAppData=')[1].split('&tgWebAppVersion')[0]))
self.user_id = tg_web_data.split('"id":')[1].split(',"first_name"')[0]
self.first_name = tg_web_data.split('"first_name":"')[1].split('","last_name"')[0]
self.last_name = tg_web_data.split('"last_name":"')[1].split('","username"')[0]
if self.tg_client.is_connected:
await self.tg_client.disconnect()
return tg_web_data1
except InvalidSession as error:
raise error
except Exception as error:
traceback.print_exc()
logger.error(f"<light-yellow>{self.session_name}</light-yellow> | Unknown error during Authorization: "
f"{error}")
await asyncio.sleep(delay=3)
def random_fingerprint(self, lengths=32):
return ''.join(choices('0123456789abcdef', k=lengths))
def generate_Fvideo_token(self, length):
characters = string.ascii_letters + string.digits + "+/"
digits = string.digits
characters1 = string.ascii_letters + digits
random_string = ''.join(choice(characters) for _ in range(length - 3))
random_string += '='
random_string += choice(digits)
random_string += choice(characters1)
return random_string
fake = Faker()
def get_random_resolution(self):
width = randint(720, 1920)
height = randint(720, 1080)
return f"{width},{height}"
def get_random_timezone(self):
timezones = [
"GMT+07:00", "GMT+05:30", "GMT-08:00", "GMT+00:00", "GMT+03:00"
]
return choice(timezones)
def get_random_timezone_offset(self, timezone):
# Extract the offset from the timezone format "GMT+07:00"
sign = 1 if "+" in timezone else -1
hours = int(timezone.split("GMT")[1].split(":")[0])
return sign * hours * 60
def get_random_plugins(self):
plugins = [
"PDF Viewer,Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,WebKit built-in PDF",
"Flash,Java,Silverlight,QuickTime",
"Chrome PDF Viewer,Widevine Content Decryption Module",
]
return choice(plugins)
def get_random_canvas_code(self):
return ''.join(choices(lower(string.hexdigits), k=8))
def get_random_fingerprint(self):
return ''.join(choices(lower(string.hexdigits), k=32))
def generate_random_data(self, user_agent):
timezone = self.get_random_timezone()
sol = self.get_random_resolution()
data = {
"screen_resolution": sol,
"available_screen_resolution": sol,
"system_version": fake.random_element(["Windows 10", "Windows 11", "Ubuntu 20.04"]),
"brand_model": fake.random_element(["unknown", "Dell XPS 13", "HP Spectre"]),
"system_lang": "en-EN",
"timezone": timezone,
"timezoneOffset": self.get_random_timezone_offset(timezone),
"user_agent": user_agent,
"list_plugin": self.get_random_plugins(),
"canvas_code": self.get_random_canvas_code(),
"webgl_vendor": fake.company(),
"webgl_renderer": f"ANGLE ({fake.company()}, {fake.company()} Graphics)",
"audio": str(uniform(100, 130)),
"platform": fake.random_element(["Win32", "Win64"]),
"web_timezone": fake.timezone(),
"device_name": f"{fake.user_agent()} ({fake.random_element(['Windows'])})",
"fingerprint": self.get_random_fingerprint(),
"device_id": "",
"related_device_ids": ""
}
return data
async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy):
try:
response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5), ssl=False)
ip = (await response.json()).get('origin')
logger.info(f"{self.session_name} | Proxy IP: {ip}")
return True
except Exception as error:
logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
return False
def setup_session(self, session: cloudscraper.CloudScraper):
payload = {
"queryString": self.auth_token,
"socialType": "telegram"
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/third-party/access/accessToken",
headers=headers, json=payload)
data_ = response.json()
if data_['code'] == '000000':
logger.success(f"{self.session_name} | <green>Get access token sucessfully</green>")
self.access_token = data_['data']['accessToken']
else:
logger.warning(f"{self.session_name} | <red>Get access token failed: {data_}</red>")
def random_data_type(self, type, end_time, item_size, item_pts, pos_y: float):
# I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !
# end_time = int(end_time)
if type == 1:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
hook_hit_y = "{:.3f}".format(pos_y)
multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
hook_shot_angle = "{:.3f}".format(cal_angle)
item_type = 1
item_s = item_size
point = randint(1, 200)
elif type == 2:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
# hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
hook_hit_y = "{:.3f}".format(pos_y)
multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
hook_shot_angle = "{:.3f}".format(cal_angle)
item_type = 2
item_s = item_size
point = int(item_size) + int(item_pts)
elif type == 0:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
# hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
hook_hit_y = "{:.3f}".format(pos_y)
multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
hook_shot_angle = "{:.3f}".format(cal_angle)
item_type = 0
item_s = item_size
point = randint(1, 200)
else:
pick_time = self.curr_time + self.rs
if pick_time >= end_time:
pick_time = end_time - 1000
return None
hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
hook_hit_x = 0
hook_hit_y = 0
item_type = randint(0, 2)
item_s = randint(1, 100)
point = randint(1, 200)
# 1727080937255|272.705|208.070|-0.944|0|0|2|38|12;1727080938339|224.985|241.018|-0.432|249.685|294.600|1|70|182;1727080941172|124.175|241.530|0.420|0|0|2|57|186;1727080943373|77.580|210.808|0.910|0|0|2|7|140;1727080944891|181.929|250.277|-0.066|189.091|359.041|2|60|90;1727080948123|269.666|211.426|-0.902|0|0|2|92|11;1727080949024|279.568|199.250|-1.047|0|0|2|60|34;1727080950908|162.174|250.020|0.096|144.951|428.190|0|30|191;1727080953975|78.758|212.055|0.895|0|0|0|1|151;1727080955243|133.916|244.791|0.334|103.100|333.596|1|30|15;1727080957193|278.835|200.291|-1.035|0|0|1|5|150;1727080959444|209.788|245.932|-0.298|303.593|550.828|1|70|72;1727080965178|87.635|220.354|0.786|0|0|1|85|73;1727080967129|168.297|250.390|0.046|156.376|509.116|1|50|110;1727080971647|188.297|249.779|-0.118|209.403|427.530|1|30|30;1727080974548|145.269|252.269|0.237|105.591|416.545|1|30|92;1727080978299|172.753|252.036|0.010|168.866|661.017|1|50|13
data = f"{pick_time}|{hook_pos_x}|{hook_pos_y}|{hook_shot_angle}|{hook_hit_x}|{hook_hit_y}|{item_type}|{item_s}|{point}"
return data
def encrypt(self, text, key):
iv = get_random_bytes(12)
iv_base64 = base64_encode(iv)
# print(iv_base64[:16].encode('utf-8'))
cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv_base64[:16].encode('utf-8'))
ciphertext = cipher.encrypt(pad(text.encode('utf-8'), AES.block_size))
ciphertext_base64 = base64_encode(ciphertext)
return iv_base64 + ciphertext_base64
def get_game_data(self):
# I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !
try:
end_time = int((time() + 45) * 1000)
# print(end_time)
random_pick_time = randint(8, 15)
total_obj = 0
key_for_game = self.game_response['data']['gameTag']
obj_type = {
"coin": {},
"trap": {},
"bonus": ""
}
for obj in self.game_response['data']['cryptoMinerConfig']['itemSettingList']:
total_obj += obj['quantity']
if obj['type'] == "BONUS":
obj_type['bonus'] = f"{obj['rewardValueList'][0]},{obj['size']}"
else:
for reward in obj['rewardValueList']:
if int(reward) > 0:
obj_type['coin'].update({reward: f"{obj['size']},{obj['quantity']}"})
else:
obj_type['trap'].update({abs(int(reward)): f"{obj['size']},{obj['quantity']}"})
limit = min(total_obj, random_pick_time)
random_pick_sth_times = randint(1, limit)
picked_bonus = False
picked = 0
logger.info(f"{self.session_name} | Playing game!")
game_data_payload = []
score = 0
# print(obj_type)
pos_y = []
for i in range(random_pick_sth_times + 5):
pos_y.append(uniform(250, 550))
sorted_pos_y = sorted(pos_y)
for i in range(1, len(sorted_pos_y)):
if sorted_pos_y[i] - sorted_pos_y[i - 1] < 40:
sorted_pos_y[i] += randint(40, 55)
Total_tap = 0
while end_time > self.curr_time and picked < random_pick_sth_times:
self.rs = randint(2500, 4000)
random_reward = randint(1, 100)
if random_reward <= 20:
if len(list(obj_type['trap'].keys())) > 0:
picked += 1
reward_d = choice(list(obj_type['trap'].keys()))
quantity = obj_type['trap'][reward_d].split(',')[1]
item_size = obj_type['trap'][reward_d].split(',')[0]
if int(quantity) > 0:
data_ = self.random_data_type(end_time=end_time,
type=0,
item_size=int(item_size),
item_pts=0,
pos_y=sorted_pos_y[Total_tap])
if data_ is not None:
Total_tap += 1
score = max(0, score - int(reward_d))
game_data_payload.append(data_)
if int(quantity) - 1 > 0:
obj_type['trap'].update({reward_d: f"{item_size},{int(quantity) - 1}"})
else:
obj_type["trap"].pop(reward_d)
else:
break
elif random_reward > 20 and random_reward <= 70:
if len(list(obj_type['coin'].keys())) > 0:
picked += 1
reward_d = choice(list(obj_type['coin'].keys()))
quantity = obj_type['coin'][reward_d].split(',')[1]
item_size = obj_type['coin'][reward_d].split(',')[0]
if int(quantity) > 0:
data_ = self.random_data_type(end_time=end_time,
type=1,
item_size=item_size,
item_pts=0,
pos_y=sorted_pos_y[Total_tap])
if data_ is not None:
Total_tap += 1
score += int(reward_d)
game_data_payload.append(data_)
if int(quantity) - 1 > 0:
obj_type['coin'].update({reward_d: f"{item_size},{int(quantity) - 1}"})
else:
obj_type["coin"].pop(reward_d)
else:
break
elif random_reward > 70 and random_reward <= 100 and picked_bonus is False:
picked += 1
size = obj_type['bonus'].split(',')[1]
pts = obj_type['bonus'].split(',')[0]
data_ = self.random_data_type(end_time=end_time,
type=2,
item_size=size,
item_pts=pts,
pos_y=sorted_pos_y[Total_tap])
if data_ is not None:
Total_tap += 1
picked_bonus = True
score += int(pts)
game_data_payload.append(data_)
self.curr_time += self.rs
if len(game_data_payload) > 0:
data_pl = ';'.join(game_data_payload)
# print(data_pl)
game_payload = self.encrypt(data_pl, key_for_game)
self.game = {
"payload": game_payload,
"log": score,
"debug": data_pl
}
# print(self.game)
return True
else:
logger.warning(f"{self.session_name} | <yellow>Failed to play game, reason: Time out</yellow>")
return False
except Exception as error:
traceback.print_exc()
logger.error(f"{self.session_name} | <red>Unknown error while trying to get game data: {str(error)}</red>")
return False
def setup_account(self, session: cloudscraper.CloudScraper):
ref_id = settings.REF_LINK.split("=")[1].split('&')[0].split('_')[1]
payload = {
"agentId": str(ref_id),
"resourceId": 2056
}
res = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/referral",
headers=headers,
json=payload)
json_d = res.json()
if json_d['success']:
res = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/participated",
headers=headers, json=payload)
json_d = res.json()
if json_d['success']:
logger.success(f"{self.session_name} | <green>Successfully set up account !</green>")
login_task = {
"resourceId": 2057
}
complete = self.complete_task(session, login_task)
if complete == "done":
logger.success(f"{self.session_name} | <green>Successfully checkin for the first time !</green>")
else:
logger.warning(
f"{self.session_name} | <yellow>Unknown error while tryng to init account: {json_d}</yellow>")
async def get_user_info(self, session: cloudscraper.CloudScraper):
payload = {
"resourceId": 2056
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
headers=headers, json=payload)
data_ = response.json()
# print(data_)
if data_['code'] == '000000':
# print(data_)
data__ = data_['data']
if data__['participated'] is False:
logger.info(f"{self.session_name} | Attempt to set up account...")
self.setup_account(session)
await asyncio.sleep(uniform(3, 5))
await self.get_user_info(session)
else:
logger.info(f"{self.session_name} | <cyan>Logged in</cyan>")
logger.info(
f"{self.session_name} | Total point: <yellow>{data__['metaInfo']['totalGrade']}</yellow> | <white>Risk Passed: <red>{data__['riskPassed']}</red> | Qualified: <red>{data__['qualified']}</red></white>")
else:
logger.warning(f"{self.session_name} | <red>Get user data failed: {data_}</red>")
def get_user_info1(self, session: cloudscraper.CloudScraper):
payload = {
"resourceId": 2056
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
headers=headers, json=payload)
data_ = response.json()
if data_['code'] == '000000':
# print(data_)
data__ = data_['data']
return data__
else:
logger.warning(f"{self.session_name} | <red>Get ticket data failed: {data_}</red>")
def get_task_list(self, session: cloudscraper.CloudScraper):
payload = {
"resourceId": 2056
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/list",
headers=headers, json=payload)
data_ = response.json()
# print(data_)
if data_['code'] == '000000':
task_list = data_['data']['data'][0]['taskList']['data'] # bruh what are they doing ????
tasks = []
for task in task_list:
# print(task)
if task['type'] == "THIRD_PARTY_BIND":
continue
elif task['status'] == "COMPLETED":
continue
elif task['status'] == "IN_PROGRESS":
tasks.append(task)
return tasks
else:
logger.warning(f"{self.session_name} | <red>Get tasks list failed: {data_}</red>")
return None
def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
task_ids = [task['resourceId']]
payload = {
"referralCode": "null",
"resourceIdList": task_ids
}
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/complete",
headers=headers, json=payload)
data_ = response.json()
# print(data_)
if data_['success']:
return "done"
else:
return data_['messageDetail']
def complete_game(self, session: cloudscraper.CloudScraper):
string_payload = self.game['payload']
payload = {
"log": self.game['log'],
"payload": string_payload,
"resourceId": 2056
}
# print(payload)
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/complete",
headers=headers, json=payload)
data_ = response.json()
if data_['success']:
logger.success(
f"{self.session_name} | <green>Sucessfully earned: <yellow>{self.game['log']}</yellow> from game !</green>")
else:
logger.warning(
f"{self.session_name} | <yellow>Failed to complete game | {self.game['log']}: {data_}</yellow>")
def auto_update_ticket(self, session: cloudscraper.CloudScraper):
ticket_data = self.get_user_info1(session)
return ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']
async def play_game(self, session: cloudscraper.CloudScraper):
ticket_data = self.get_user_info1(session)
if ticket_data['metaInfo']['totalAttempts'] == ticket_data['metaInfo']['consumedAttempts']:
logger.warning(f"{self.session_name} | No Attempt left to play game...")
return
attempt_left = ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']
logger.info(f"{self.session_name} | Starting to play game...")
while attempt_left > 0:
# await asyncio.sleep(1000)
logger.info(f"{self.session_name} | Attempts left: <cyan>{attempt_left}</cyan>")
payload = {
"resourceId": 2056
}
headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
# print(headers)
response = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
headers=headers, json=payload)
if response.status_code == 200:
data_ = response.json()
# print(data_)
if 'sessionId' in data_['data']:
# print("ok")
sessionId = data_['data']['sessionId']
captcha_data = f"bizId=tg_mini_game_play&sv=20220812&lang=en&securityCheckResponseValidateId={data_['data']['securityCheckValidateId']}&clientType=web"
captcha_header = {
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"content-type": "text/plain; charset=UTF-8",
"bnc-uuid": "xxx",
"captcha-sdk-version": "1.0.0",
"clienttype": "web",
"device-info": headers['Device-Info'],
"fvideo-id": "xxx",
"origin": "https://www.binance.com",
"referer": "https://www.binance.com/",
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
"user-agent": headers["User-Agent"],
"x-captcha-se": "true"
}
cap_res = session.post("https://api.commonservice.io/gateway-api/v1/public/antibot/getCaptcha",
headers=captcha_header, data=captcha_data)
if cap_res.status_code == 200:
# print(cap_res.text)
captcha_data_ = cap_res.json()['data']
cap_type = captcha_data_['captchaType']
bizId = captcha_data
sig = captcha_data_['sig']
salt = captcha_data_['salt']
tag = captcha_data_['tag']
path2 = captcha_data_['path2']
ek = captcha_data_['ek']
logger.info(f"{self.session_name} | Attempt to solve captcha ({tag})...")
captcha_data = {
"sig": sig,
"salt": salt,
"path2": path2,
"ek": ek,
"captchaType": cap_type,
"tag": tag
}
# dat = {
# "mode": "VANHBAKA",
# "bizId": bizId,
# "captchaData": {
# "sig": sig,
# "salt": salt,
# "path2": path2,
# "ek": ek,
# "captchaType": cap_type,
# "tag": tag
# }
# }
# head = {
# "user_id": self.user_id
# }
#
# solve = session.post("http://127.0.0.1:5000/captcha/solve", json=dat, headers=head)
# solve1 = solve.json()
# print(solve1)
# print(payload)
from bot.core.solver.captcha_solver import solve_captcha
solve = await solve_captcha(bizId, captcha_data)
# print(solve)
await asyncio.sleep(random.uniform(2,4))
if solve['ok']:
sol = solve['solution']
# print(sol)
vaild_captcha = f"{bizId}&data={sol['payload']}&s={sol['s']}&sig={sig}"
# print(vaild_captcha)
solver = session.post(
"https://api.commonservice.io/gateway-api/v1/public/antibot/validateCaptcha",
data=vaild_captcha, headers=captcha_header)
if solver.status_code == 200:
# print(solver.json())
captcha_token = solver.json()['data']['token']
if captcha_token == "":
logger.warning(
f"{self.session_name} | <yellow>Failed to solve captcha. Try again next round...</yellow>")
sleep_ = uniform(10, 15)
logger.info(f"{self.session_name} | Sleep {sleep_}s...")
await asyncio.sleep(sleep_)
continue
logger.success(f"{self.session_name} | <green>Solved captcha successfully | Solve time: <cyan>{solve['solveTime']}s</cyan></green>")
headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
start_game_header = headers.copy()
start_game_header['X-Captcha-Challenge'] = sig
start_game_header['X-Captcha-Session-Id'] = sessionId
start_game_header['X-Captcha-Token'] = captcha_token
payload = {
"resourceId": 2056
}
# print(start_game_header)
res_d = session.post(
"https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
headers=start_game_header, json=payload)
data_ = res_d.json()
# print(data_)
attempt_left = self.auto_update_ticket(session)
if data_['success']:
logger.success(
f"{self.session_name} | <green>Game <cyan>{data_['data']['gameTag']}</cyan> started successful</green>")
self.game_response = data_
# print(data_)
sleep_ = uniform(45, 45.05)
self.curr_time = int((time() * 1000))
check = self.get_game_data()
if check:
logger.info(
f"{self.session_name} | Wait <white>{sleep_}s</white> to complete the game...")
await asyncio.sleep(sleep_)
self.complete_game(session)
else:
print(response.text)
logger.warning(f"Start game failed: {response.status_code}")
sleep_ = uniform(20, 25)
logger.info(f"{self.session_name} | Sleep {sleep_}s...")
await asyncio.sleep(sleep_)
async def run(self, proxy: str | None) -> None:
access_token_created_time = 0
proxy_conn = ProxyConnector().from_url(proxy) if proxy else None
headers["User-Agent"] = generate_random_user_agent(device_type='android', browser_type='chrome')
http_client = CloudflareScraper(headers=headers, connector=proxy_conn)
session = cloudscraper.create_scraper()
if proxy:
proxy_check = await self.check_proxy(http_client=http_client, proxy=proxy)
if proxy_check:
proxy_type = proxy.split(':')[0]
proxies = {
proxy_type: proxy
}
session.proxies.update(proxies)
logger.info(f"{self.session_name} | bind with proxy ip: {proxy}")
token_live_time = randint(28700, 28800)
while True:
try:
if time() - access_token_created_time >= token_live_time:
tg_web_data = await self.get_tg_web_data(proxy=proxy)
self.auth_token = tg_web_data
data = self.generate_random_data(headers['User-Agent'])
json_data = json.dumps(data)
encoded_data = base64.b64encode(json_data.encode()).decode()
headers['Device-Info'] = encoded_data
# print(encoded_data)
fvideo_token = self.generate_Fvideo_token(196)
headers['X-Tg-User-Id'] = self.user_id
# print(self.user)
headers['Fvideo-Id'] = secrets.token_hex(20)
headers['Fvideo-Token'] = fvideo_token
headers['Bnc-Uuid'] = str(uuid.uuid4())
headers['Cookie'] = f"theme=dark; bnc-uuid={headers['Bnc-Uuid']};"
# print(fvideo_token)
self.setup_session(session)
access_token_created_time = time()
token_live_time = randint(3500, 3600)
if self.access_token:
headers['X-Growth-Token'] = self.access_token
await self.get_user_info(session)
if settings.AUTO_TASK:
task_list = self.get_task_list(session)
for task in task_list:
check = self.complete_task(session, task)
if check == "done":
logger.success(
f"{self.session_name} | <green>Successfully completed task <cyan>{task['type']}</cyan> | Reward: <yellow>{task['rewardList'][0]['amount']}</yellow></green>")
else:
logger.warning(
f"{self.session_name} | <light-yellow> Failed to complete task: {task['type']}, msg: {check}</light-yellow>")
await asyncio.sleep(uniform(3, 5))
if settings.AUTO_PLAY_GAME:
await self.play_game(session)
logger.info(f"<light-blue>==Completed {self.session_name}==</light-blue>")
session.close()
await http_client.close()
# session.close()
break
except InvalidSession as error:
raise error
except Exception as error:
traceback.print_exc()
logger.error(f"{self.session_name} | Unknown error: {error}")
await asyncio.sleep(delay=randint(60, 120))
async def run_tapper_no_thread(tg_clients, proxies):
proxies_cycle = cycle(proxies) if proxies else None
while True:
for tg_client in tg_clients:
try:
await Tapper(tg_client=tg_client).run(next(proxies_cycle) if proxies_cycle else None)
except InvalidSession:
logger.error(f"{tg_client.name} | Invalid Session")
sleep_ = randint(settings.DELAY_EACH_ACCOUNT[0], settings.DELAY_EACH_ACCOUNT[1])
logger.info(f"Sleep {sleep_}s...")
await asyncio.sleep(sleep_)
sleep_ = randint(1500, 2500)
logger.info(f"<red>Sleep {sleep_}s...</red>")
await asyncio.sleep(sleep_)
================================================
FILE: bot/exceptions/__init__.py
================================================
class InvalidSession(BaseException):
...
================================================
FILE: bot/utils/__init__.py
================================================
from .logger import logger
from . import launcher
import os
if not os.path.exists(path="sessions"):
os.mkdir(path="sessions")
================================================
FILE: bot/utils/launcher.py
================================================
import os
import glob
import argparse
import sys
import requests
from pyrogram import Client
from better_proxy import Proxy
from bot.config import settings
from bot.utils import logger
from bot.core.tapper import run_tapper_no_thread
from bot.core.query import run_tapper_no_thread_query
from bot.core.registrator import register_sessions
import importlib.util
curr_version = "3.0.5"
version = requests.get("https://raw.githubusercontent.com/vanhbakaa/moonbix-bot/refs/heads/main/version")
version_ = version.text.strip()
if curr_version == version_:
logger.info("<cyan>Your version is up to date!</cyan>")
else:
logger.warning(f"<yellow>New version detected {version_} please update the bot!</yellow>")
sys.exit()
start_text = f"""
Version: {curr_version}
By: https://github.com/vanhbakaa
Select an action:
1. Run clicker (session)
2. Create session
3. Run Cheat Tapper
4. Run clicker (Query)
"""
global tg_clients
def import_tapper():
# Define the relative file path
file_path = os.path.join(os.getcwd(), "bot/core/tapperCheatPoint.py")
# Define a module name for the imported module
module_name = "tapper"
# Check if the file exists
if os.path.exists(file_path):
# Dynamically load the module
spec = importlib.util.spec_from_file_location(module_name, file_path)
tapper_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(tapper_module)
sys.modules[module_name] = tapper_module
print(f"Successfully imported '{file_path}' as module '{module_name}'")
return tapper_module
else:
print(f"Join my telegram channel to use this option!")
return None
def get_session_names() -> list[str]:
session_names = sorted(glob.glob("sessions/*.session"))
session_names = [
os.path.splitext(os.path.basename(file))[0] for file in session_names
]
return session_names
def get_proxies() -> list[Proxy]:
if settings.USE_PROXY_FROM_FILE:
with open(file="bot/config/proxies.txt", encoding="utf-8-sig") as file:
proxies = [Proxy.from_str(proxy=row.strip()).as_url for row in file]
else:
proxies = []
return proxies
async def get_tg_clients() -> list[Client]:
global tg_clients
session_names = get_session_names()
if not session_names:
raise FileNotFoundError("Not found session files")
if not settings.API_ID or not settings.API_HASH:
raise ValueError("API_ID and API_HASH not found in the .env file.")
tg_clients = [
Client(
name=session_name,
api_id=settings.API_ID,
api_hash=settings.API_HASH,
workdir="sessions/",
plugins=dict(root="bot/plugins"),
)
for session_name in session_names
]
return tg_clients
async def process() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--action", type=int, help="Action to perform")
logger.info(f"Detected {len(get_session_names())} sessions | {len(get_proxies())} proxies")
action = parser.parse_args().action
if not action:
print(start_text)
while True:
action = input("> ")
if not action.isdigit():
logger.warning("Action must be number")
elif action not in ["1", "2", "3", "4"]:
logger.warning("Action must be 1, 2, 3 or 4")
else:
action = int(action)
break
if action == 2:
await register_sessions()
elif action == 1:
tg_clients = await get_tg_clients()
proxies = get_proxies()
await run_tapper_no_thread(tg_clients=tg_clients, proxies=proxies)
elif action == 3:
tapper = import_tapper()
if tapper:
tg_clients = await get_tg_clients()
proxies = get_proxies()
await tapper.run_tapper_no_thread(tg_clients=tg_clients, proxies=proxies)
elif action == 4:
with open("data.txt", "r") as f:
query_ids = [line.strip() for line in f.readlines()]
proxies = get_proxies()
await run_tapper_no_thread_query(query_ids, proxies)
================================================
FILE: bot/utils/logger.py
================================================
import sys
from loguru import logger
logger.remove()
logger.add(sink=sys.stdout, format="<white>{time:YYYY-MM-DD HH:mm:ss}</white>"
" | <level>{level: <8}</level>"
" | <cyan><b>{line}</b></cyan>"
" - <white><b>{message}</b></white>")
logger = logger.opt(colors=True)
================================================
FILE: main.py
================================================
import asyncio
from contextlib import suppress
from bot.utils.launcher import process
async def main():
await process()
if __name__ == '__main__':
with suppress(KeyboardInterrupt):
asyncio.run(main())
================================================
FILE: requirements.txt
================================================
aiocfscrape==1.0.0
aiohttp==3.9.3
aiohttp-proxy==0.1.2
aiosignal==1.3.1
annotated-types==0.6.0
async-timeout==4.0.3
attrs==23.2.0
beautifulsoup4==4.12.3
better-proxy==1.1.5
colorama==0.4.6
DateTime==5.5
frozenlist==1.4.1
idna==3.6
Js2Py==0.74
loguru==0.7.2
multidict==6.0.5
pyaes==1.6.1
pydantic==2.6.4
pydantic-settings==2.2.1
pydantic_core==2.16.3
pyjsparser==2.7.1
Pyrogram==2.0.106
PySocks==1.7.1
python-dotenv==1.0.1
pytz==2024.1
six==1.16.0
soupsieve==2.5
TgCrypto==1.2.5
typing_extensions==4.11.0
tzdata==2024.1
tzlocal==5.2
websockets==12.0
win32-setctime==1.1.0
yarl==1.9.4
zope.interface==6.4.post2
requests==2.32.3
cloudscraper==1.2.71
Faker==29.0.0
pycryptodome==3.20.0
pillow==10.4.0
transformers==4.45.1
torch==2.4.1
================================================
FILE: run.bat
================================================
@echo off
if not exist venv (
echo Creating virtual environment...
python -m venv venv
)
echo Activating virtual environment...
call venv\Scripts\activate
if not exist venv\Lib\site-packages\installed (
if exist requirements.txt (
echo installing wheel for faster installing
pip install wheel
echo Installing dependencies...
pip install -r requirements.txt
echo. > venv\Lib\site-packages\installed
) else (
echo requirements.txt not found, skipping dependency installation.
)
) else (
echo Dependencies already installed, skipping installation.
)
if not exist .env (
echo Copying configuration file
copy .env-example .env
) else (
echo Skipping .env copying
)
echo Starting the bot...
python main.py
echo done
echo PLEASE EDIT .ENV FILE
pause
================================================
FILE: run.sh
================================================
#!/bin/bash
# Проверка на наличие папки venv
if [ ! -d "venv" ]; then
echo "Creating virtual environment..."
python3 -m venv venv
fi
echo "Activating virtual environment..."
source venv/bin/activate
# Проверка на наличие установленного флага в виртуальном окружении
if [ ! -f "venv/installed" ]; then
if [ -f "requirements.txt" ]; then
echo "Installing wheel for faster installing"
pip3 install wheel
echo "Installing dependencies..."
pip3 install -r requirements.txt
touch venv/installed
else
echo "requirements.txt not found, skipping dependency installation."
fi
else
echo "Dependencies already installed, skipping installation."
fi
if [ ! -f ".env" ]; then
echo "Copying configuration file"
cp .env-example .env
else
echo "Skipping .env copying"
fi
echo "Starting the bot..."
python3 main.py
echo "done"
echo "PLEASE EDIT .ENV FILE"
================================================
FILE: version
================================================
3.0.5
gitextract_smur5s11/ ├── .env-example ├── .gitignore ├── LICENSE ├── README.md ├── bot/ │ ├── __init__.py │ ├── config/ │ │ ├── __init__.py │ │ ├── config.py │ │ └── proxies.txt │ ├── core/ │ │ ├── __init__.py │ │ ├── agents.py │ │ ├── headers.py │ │ ├── query.py │ │ ├── registrator.py │ │ ├── solver/ │ │ │ ├── captcha/ │ │ │ │ ├── events.cp311-win_amd64.pyd │ │ │ │ ├── payload.cp311-win_amd64.pyd │ │ │ │ └── utils.cp311-win_amd64.pyd │ │ │ ├── captcha_solver.cp311-win_amd64.pyd │ │ │ └── classify/ │ │ │ ├── classifier.cp311-win_amd64.pyd │ │ │ └── image.py │ │ └── tapper.py │ ├── exceptions/ │ │ └── __init__.py │ └── utils/ │ ├── __init__.py │ ├── launcher.py │ └── logger.py ├── main.py ├── requirements.txt ├── run.bat ├── run.sh └── version
SYMBOL INDEX (66 symbols across 9 files)
FILE: bot/config/config.py
class Settings (line 4) | class Settings(BaseSettings):
FILE: bot/core/agents.py
function generate_random_user_agent (line 4) | def generate_random_user_agent(device_type='android', browser_type='chro...
FILE: bot/core/query.py
function base64_encode (line 43) | def base64_encode(data):
class Tapper (line 47) | class Tapper:
method __init__ (line 48) | def __init__(self, query: str, accname: str):
method random_fingerprint (line 67) | def random_fingerprint(self, lengths=32):
method generate_Fvideo_token (line 70) | def generate_Fvideo_token(self, length):
method get_random_resolution (line 86) | def get_random_resolution(self):
method get_random_timezone (line 91) | def get_random_timezone(self):
method get_random_timezone_offset (line 97) | def get_random_timezone_offset(self, timezone):
method get_random_plugins (line 103) | def get_random_plugins(self):
method get_random_canvas_code (line 111) | def get_random_canvas_code(self):
method get_random_fingerprint (line 114) | def get_random_fingerprint(self):
method generate_random_data (line 117) | def generate_random_data(self, user_agent):
method check_proxy (line 143) | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy:...
method setup_session (line 153) | def setup_session(self, session: cloudscraper.CloudScraper):
method random_data_type (line 168) | def random_data_type(self, type, end_time, item_size, item_pts, pos_y:...
method encrypt (line 251) | def encrypt(self, text, key):
method get_game_data (line 260) | def get_game_data(self):
method setup_account (line 390) | def setup_account(self, session: cloudscraper.CloudScraper):
method get_user_info (line 419) | async def get_user_info(self, session: cloudscraper.CloudScraper):
method get_user_info1 (line 444) | def get_user_info1(self, session: cloudscraper.CloudScraper):
method get_task_list (line 459) | def get_task_list(self, session: cloudscraper.CloudScraper):
method complete_task (line 484) | def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
method complete_game (line 500) | def complete_game(self, session: cloudscraper.CloudScraper):
method auto_update_ticket (line 520) | def auto_update_ticket(self, session: cloudscraper.CloudScraper):
method play_game (line 524) | async def play_game(self, session: cloudscraper.CloudScraper):
method run (line 678) | async def run(self, proxy: str | None) -> None:
function run_tapper_no_thread_query (line 752) | async def run_tapper_no_thread_query(queryids, proxies):
FILE: bot/core/registrator.py
function register_sessions (line 7) | async def register_sessions() -> None:
FILE: bot/core/solver/classify/image.py
function process_image (line 5) | async def process_image(url):
FILE: bot/core/tapper.py
function base64_encode (line 43) | def base64_encode(data):
class Tapper (line 47) | class Tapper:
method __init__ (line 48) | def __init__(self, tg_client: Client):
method get_tg_web_data (line 65) | async def get_tg_web_data(self, proxy: str | None) -> str:
method random_fingerprint (line 132) | def random_fingerprint(self, lengths=32):
method generate_Fvideo_token (line 135) | def generate_Fvideo_token(self, length):
method get_random_resolution (line 151) | def get_random_resolution(self):
method get_random_timezone (line 156) | def get_random_timezone(self):
method get_random_timezone_offset (line 162) | def get_random_timezone_offset(self, timezone):
method get_random_plugins (line 168) | def get_random_plugins(self):
method get_random_canvas_code (line 176) | def get_random_canvas_code(self):
method get_random_fingerprint (line 179) | def get_random_fingerprint(self):
method generate_random_data (line 182) | def generate_random_data(self, user_agent):
method check_proxy (line 208) | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy:...
method setup_session (line 218) | def setup_session(self, session: cloudscraper.CloudScraper):
method random_data_type (line 233) | def random_data_type(self, type, end_time, item_size, item_pts, pos_y:...
method encrypt (line 316) | def encrypt(self, text, key):
method get_game_data (line 325) | def get_game_data(self):
method setup_account (line 455) | def setup_account(self, session: cloudscraper.CloudScraper):
method get_user_info (line 484) | async def get_user_info(self, session: cloudscraper.CloudScraper):
method get_user_info1 (line 509) | def get_user_info1(self, session: cloudscraper.CloudScraper):
method get_task_list (line 524) | def get_task_list(self, session: cloudscraper.CloudScraper):
method complete_task (line 549) | def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
method complete_game (line 565) | def complete_game(self, session: cloudscraper.CloudScraper):
method auto_update_ticket (line 585) | def auto_update_ticket(self, session: cloudscraper.CloudScraper):
method play_game (line 589) | async def play_game(self, session: cloudscraper.CloudScraper):
method run (line 743) | async def run(self, proxy: str | None) -> None:
function run_tapper_no_thread (line 817) | async def run_tapper_no_thread(tg_clients, proxies):
FILE: bot/exceptions/__init__.py
class InvalidSession (line 1) | class InvalidSession(BaseException):
FILE: bot/utils/launcher.py
function import_tapper (line 43) | def import_tapper():
function get_session_names (line 64) | def get_session_names() -> list[str]:
function get_proxies (line 73) | def get_proxies() -> list[Proxy]:
function get_tg_clients (line 83) | async def get_tg_clients() -> list[Client]:
function process (line 108) | async def process() -> None:
FILE: main.py
function main (line 7) | async def main():
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (111K chars).
[
{
"path": ".env-example",
"chars": 129,
"preview": "API_ID=\nAPI_HASH=\n\nREF_LINK=\nAUTO_TASK=\nAUTO_PLAY_GAME=\nDELAY_EACH_ACCOUNT=\n\nMORE_ACCURATE_CAPTCHA_SOLVER=\n\nUSE_PROXY_FR"
},
{
"path": ".gitignore",
"chars": 23,
"preview": ".env\nsessions\ndata.txt\n"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 5426,
"preview": "## Recommendation before use\n\n# Join the bot [here](https://t.me/Binance_Moonbix_bot/start?startApp=ref_6624523270&start"
},
{
"path": "bot/__init__.py",
"chars": 20,
"preview": "__version__ = '1.0'\n"
},
{
"path": "bot/config/__init__.py",
"chars": 29,
"preview": "from .config import settings\n"
},
{
"path": "bot/config/config.py",
"chars": 562,
"preview": "from pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nclass Settings(BaseSettings):\n model_config = Settin"
},
{
"path": "bot/config/proxies.txt",
"chars": 145,
"preview": "http://38.154.227.167:5868:vanhbaka:Vanhdayyyy\r\nhttp://45.127.248.127:5128:vanhbaka:Vanhdayyyy\r\nhttp://207.244.217.165:6"
},
{
"path": "bot/core/__init__.py",
"chars": 19,
"preview": "__version__ = '1.0'"
},
{
"path": "bot/core/agents.py",
"chars": 3871,
"preview": "import random\n\n\ndef generate_random_user_agent(device_type='android', browser_type='chrome'):\n chrome_versions = list"
},
{
"path": "bot/core/headers.py",
"chars": 717,
"preview": "headers = {\n 'Accept': '*/*',\n 'Accept-Language': 'en-US',\n \"Bnc-Uuid\": \"\",\n 'Clienttype': \"web\",\n 'Conte"
},
{
"path": "bot/core/query.py",
"chars": 36300,
"preview": "import asyncio\r\nimport json\r\nimport random\r\nimport traceback\r\nfrom itertools import cycle\r\nfrom time import time\r\nfrom u"
},
{
"path": "bot/core/registrator.py",
"chars": 751,
"preview": "from pyrogram import Client\n\nfrom bot.config import settings\nfrom bot.utils import logger\n\n\nasync def register_sessions("
},
{
"path": "bot/core/solver/classify/image.py",
"chars": 752,
"preview": "from PIL import Image\r\nimport requests\r\nfrom io import BytesIO\r\n\r\nasync def process_image(url):\r\n square_size = 110\r\n"
},
{
"path": "bot/core/tapper.py",
"chars": 37993,
"preview": "import asyncio\nimport json\nimport random\nimport traceback\nfrom itertools import cycle\nfrom time import time\nfrom urllib."
},
{
"path": "bot/exceptions/__init__.py",
"chars": 45,
"preview": "class InvalidSession(BaseException):\n ...\n"
},
{
"path": "bot/utils/__init__.py",
"chars": 133,
"preview": "from .logger import logger\nfrom . import launcher\n\n\nimport os\n\nif not os.path.exists(path=\"sessions\"):\n os.mkdir(path"
},
{
"path": "bot/utils/launcher.py",
"chars": 4407,
"preview": "import os\nimport glob\nimport argparse\nimport sys\n\nimport requests\n\nfrom pyrogram import Client\nfrom better_proxy import "
},
{
"path": "bot/utils/logger.py",
"chars": 374,
"preview": "import sys\nfrom loguru import logger\n\n\nlogger.remove()\nlogger.add(sink=sys.stdout, format=\"<white>{time:YYYY-MM-DD HH:mm"
},
{
"path": "main.py",
"chars": 222,
"preview": "import asyncio\nfrom contextlib import suppress\n\nfrom bot.utils.launcher import process\n\n\nasync def main():\n await pro"
},
{
"path": "requirements.txt",
"chars": 730,
"preview": "aiocfscrape==1.0.0\naiohttp==3.9.3\naiohttp-proxy==0.1.2\naiosignal==1.3.1\nannotated-types==0.6.0\nasync-timeout==4.0.3\nattr"
},
{
"path": "run.bat",
"chars": 811,
"preview": "@echo off\n\nif not exist venv (\n echo Creating virtual environment...\n python -m venv venv\n)\n\necho Activating virtu"
},
{
"path": "run.sh",
"chars": 906,
"preview": "#!/bin/bash\n\n# Проверка на наличие папки venv\nif [ ! -d \"venv\" ]; then\n echo \"Creating virtual environment...\"\n py"
},
{
"path": "version",
"chars": 6,
"preview": "3.0.5\n"
}
]
// ... and 5 more files (download for full content)
About this extraction
This page contains the full source code of the vanhbakaa/moonbix-bot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (103.2 KB), approximately 24.5k tokens, and a symbol index with 66 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.