From 760c853acdf88ceab9bd0b7dd7ad6cac08aa9ad6 Mon Sep 17 00:00:00 2001 From: bohd4nx Date: Mon, 3 Nov 2025 05:58:34 +0800 Subject: [PATCH] feat: Add Fragment API for TON topups, Telegram Premium purchases, and Stars transactions - Implemented Fragment API with methods for TON topups, Premium gifts, and Stars purchases. - Created configuration management using environment variables. - Added detailed README documentation for installation, configuration, and usage. - Developed utility classes for API client, wallet linking, and transaction processing. - Included example usage in main.py for easy demonstration of API functionalities. - Updated requirements.txt with necessary dependencies. --- .env.example | 11 +++ .gitignore | 25 ++++++ README-RU.md | 180 +++++++++++++++++++++++++++++++++++++++ README.md | 180 +++++++++++++++++++++++++++++++++++++++ app/__meta__.py | 4 + app/core/__init__.py | 3 + app/core/config.py | 37 ++++++++ app/methods/__init__.py | 5 ++ app/methods/premium.py | 120 ++++++++++++++++++++++++++ app/methods/stars.py | 109 ++++++++++++++++++++++++ app/methods/ton.py | 115 +++++++++++++++++++++++++ app/utils/__init__.py | 5 ++ app/utils/api_client.py | 27 ++++++ app/utils/linkWallet.py | 31 +++++++ app/utils/transaction.py | 36 ++++++++ main.py | 71 +++++++++++++++ requirements.txt | 4 + 17 files changed, 963 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 README-RU.md create mode 100644 README.md create mode 100644 app/__meta__.py create mode 100644 app/core/__init__.py create mode 100644 app/core/config.py create mode 100644 app/methods/__init__.py create mode 100644 app/methods/premium.py create mode 100644 app/methods/stars.py create mode 100644 app/methods/ton.py create mode 100644 app/utils/__init__.py create mode 100644 app/utils/api_client.py create mode 100644 app/utils/linkWallet.py create mode 100644 app/utils/transaction.py create mode 100644 main.py create mode 100644 requirements.txt diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d6691ef --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# Fragment.com cookies - copy from browser after login (Header String format) +# IMPORTANT: Use quotes to prevent semicolons from being treated as comments +COOKIES = "your_fragment_cookies_here" + +HASH = + +# TON wallet seed phrase - 12 or 24 words separated by spaces +SEED = + +# TON API key - get from https://tonconsole.com +API_KEY = diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..622263c --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Python +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python + +# Virtual environments +.venv/ +venv/ + +# IDE +.idea/ +.vscode/ + +# Logs +logs/ +*.log + +# Environment variables +.env + +# System files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/README-RU.md b/README-RU.md new file mode 100644 index 0000000..869a961 --- /dev/null +++ b/README-RU.md @@ -0,0 +1,180 @@ +
+ + +

πŸ’Ž Fragment API ΠΎΡ‚ @bohd4nx

+ +

+ Автоматизация ΠΏΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΉ TON, ΠΏΠΎΠΊΡƒΠΏΠΊΠΈ Telegram Premium ΠΈ Stars Ρ‡Π΅Ρ€Π΅Π· Fragment.com +

+ +[Π‘ΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΎΠ± ошибкС](https://github.com/bohd4nx/fragmentapi/issues) Β· [Π—Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ](https://github.com/bohd4nx/fragmentapi/issues) Β· [**Π”ΠΎΠ½Π°Ρ‚ TON**](https://app.tonkeeper.com/transfer/UQBUAa7KCx1ifmoEy6lF7j-822Dm_cE1j9SR7UWteu3jzukV) + +
+ +--- + +## ✨ ВозмоТности + +- πŸ’° **ПополнСниС TON для Ρ€Π΅ΠΊΠ»Π°ΠΌΡ‹** - ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° TON для Ρ€Π΅ΠΊΠ»Π°ΠΌΠ½Ρ‹Ρ… ΠΊΠ°ΠΌΠΏΠ°Π½ΠΈΠΉ ΠΈ ΠΏΠΎΠΊΡƒΠΏΠΊΠΈ ΠΏΠΎΠ΄Π°Ρ€ΠΊΠΎΠ² (1-1,000,000,000 TON) +- πŸ‘‘ **ΠŸΠΎΠ΄Π°Ρ€ΠΊΠΈ Telegram Premium** - ΠŸΠΎΠΊΡƒΠΏΠΊΠ° Premium подписок(3, 6 ΠΈΠ»ΠΈ 12 мСсяцСв) +- ⭐ **ΠŸΠΎΠΊΡƒΠΏΠΊΠ° Telegram Stars** - ΠŸΠΎΠΊΡƒΠΏΠΊΠ° Stars для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ (50-1,000,000 Stars) + +## πŸš€ Быстрый старт + +### 1. Установка + +```bash +git clone https://github.com/bohd4nx/FragmentAPI.git +cd FragmentAPI +pip install -r requirements.txt +``` + +### 2. Настройка + +Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ ΠΎΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅: + +```bash +cp .env.example .env +``` + +ΠžΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» `.env`: + +```env +COOKIES = your_fragment_cookies_here + +SEED = word1 word2 word3 ... word24 + +HASH = your_fragment_hash_here + +API_KEY = your_ton_api_key_here +``` + +### 3. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… + +#### πŸͺ ΠšΡƒΠΊΠΈ Fragment.com + +**ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ трСбования**: Π’ΠΎΠΉΠ΄ΠΈΡ‚Π΅ Π² свой Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ Telegram ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ TON ΠΊΠΎΡˆΠ΅Π»Ρ‘ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ΅ΠΉ. + +1. **УстановитС Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Cookie Editor**: + + - Π‘ΠΊΠ°Ρ‡Π°ΠΉΡ‚Π΅ ΠΈΠ· [Chrome Web Store](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) + - Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Π² ваш Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ + +2. **Π˜Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΡƒΠΊΠΈ**: + - ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ [Fragment.com](https://fragment.com) ΠΈ ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ вошли Π² систСму + - ΠŸΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚Π΅ страницу + - НаТмитС Π½Π° ΠΈΠΊΠΎΠ½ΠΊΡƒ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Cookie Editor + - НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ **"Export"** + - Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ **"Header String"** + - Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ β†’ Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ Π² `COOKIES` Π² вашСм `.env` Ρ„Π°ΠΉΠ»Π΅ + - **Π’Π°ΠΆΠ½ΠΎ**: Π—Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΎΡ‡ΠΊΠΈ с запятой Π½Π΅ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Π»ΠΈΡΡŒ ΠΊΠ°ΠΊ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ + +**ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚**: + +```env +COOKIES = "stel_token=;stel_dt=;stel_ssid=;stel_ton_token=" +``` + +#### πŸ” Seed-Ρ„Ρ€Π°Π·Π° TON кошСлька + +**Если Ρƒ вас Π΅Ρ‰Ρ‘ Π½Π΅Ρ‚ TON кошСлька**: + +1. **Π‘ΠΊΠ°Ρ‡Π°ΠΉΡ‚Π΅ Tonkeeper**: + + - iOS: [App Store](https://apps.apple.com/app/tonkeeper/id1587742107) + - Android: [Google Play](https://play.google.com/store/apps/details?id=com.ton_keeper) + +2. **Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΡˆΠ΅Π»Ρ‘ΠΊ**: + + - ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Tonkeeper + - НаТмитС **"Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΡˆΠ΅Π»Ρ‘ΠΊ"** + - **Π’ΠΠ–ΠΠž**: Π—Π°ΠΏΠΈΡˆΠΈΡ‚Π΅ Π²Π°ΡˆΡƒ 24-ΡΠ»ΠΎΠ²Π½ΡƒΡŽ seed-Ρ„Ρ€Π°Π·Ρƒ Π½Π° Π±ΡƒΠΌΠ°Π³Π΅ + - Π₯Ρ€Π°Π½ΠΈΡ‚Π΅ Π΅Ρ‘ Π² бСзопасном мСстС - Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄Π΅Π»ΠΈΡ‚Π΅ΡΡŒ Π΅ΠΉ Π½ΠΈ с ΠΊΠ΅ΠΌ! + - Π—Π°Π²Π΅Ρ€ΡˆΠΈΡ‚Π΅ настройку кошСлька + +3. **ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π²Π°ΡˆΡƒ seed-Ρ„Ρ€Π°Π·Ρƒ**: + - Если Ρƒ вас ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ ΠΊΠΎΡˆΠ΅Π»Ρ‘ΠΊ, ΠΏΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² Настройки β†’ Π Π΅Π·Π΅Ρ€Π²Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ + - Π’Π²Π΅Π΄ΠΈΡ‚Π΅ ваш ΠΏΠ°Ρ€ΠΎΠ»ΡŒ + - Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ 24 слова β†’ Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ Π² `SEED` Π² вашСм `.env` Ρ„Π°ΠΉΠ»Π΅ + +**Π€ΠΎΡ€ΠΌΠ°Ρ‚**: `слово1 слово2 слово3 ... слово24` + +#### πŸ”— Π₯Сш Fragment + +**ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ трСбования**: Π‘Π½Π°Ρ‡Π°Π»Π° Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚Π΅ настройку ΠΊΡƒΠΊΠΈ Π²Ρ‹ΡˆΠ΅. + +1. **ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ ΠΊΠΎΡˆΠ΅Π»Ρ‘ΠΊ ΠΊ Fragment**: + + - ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π½Π° [Fragment.com](https://fragment.com) + - Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ваш TON ΠΊΠΎΡˆΠ΅Π»Ρ‘ΠΊ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Ρ‘Π½ + - Π’ΠΎΠΉΠ΄ΠΈΡ‚Π΅ с вашим Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ΠΎΠΌ Telegram + +2. **Π˜Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Ρ…Π΅ΡˆΠ°**: + - ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ **Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°** (F12) + - НаТмитС Π½Π° Π²ΠΊΠ»Π°Π΄ΠΊΡƒ **"Π‘Π΅Ρ‚ΡŒ"** + - ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ ΠΊ [ΠΏΠΎΠΊΡƒΠΏΠΊΠ΅ Stars](https://fragment.com/stars/buy) + - Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ получатСля ΠΊΠ°ΠΊ **"Buy for myself"** + - ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚Π΅ страницу (Ctrl+R / Cmd+R) + - НайдитС сСтСвыС запросы, содСрТащиС `?hash=` + - НайдитС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ…Π΅ΡˆΠ° ΠΈ скопируйтС Π΅Π³ΠΎ β†’ Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ Π² `HASH` Π² вашСм `.env` Ρ„Π°ΠΉΠ»Π΅ + +**ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚**: `?hash=<ваш_Ρ…Π΅Ρˆ_здСсь>` + +#### πŸ”‘ API ΠΊΠ»ΡŽΡ‡ TON + +1. **ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ API ΠΊΠ»ΡŽΡ‡**: + - ΠŸΠΎΡΠ΅Ρ‚ΠΈΡ‚Π΅ [TON Console](https://tonconsole.com) + - Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ ΠΈ Π²ΠΎΠΉΠ΄ΠΈΡ‚Π΅ + - Π‘Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠΉΡ‚Π΅ Π½ΠΎΠ²Ρ‹ΠΉ API ΠΊΠ»ΡŽΡ‡ + - Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΊΠ»ΡŽΡ‡ β†’ Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ Π² `API_KEY` Π² вашСм `.env` Ρ„Π°ΠΉΠ»Π΅ + +**ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π°**: Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ [TON API](https://tonapi.io) для получСния API ΠΊΠ»ΡŽΡ‡Π°. + +### 4. ИспользованиС + +#### Запуск ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² + +```bash +python main.py +``` + +#### ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ использованиС + +```python +from app.methods import FragmentTon, FragmentPremium, FragmentStars + +# ПополнСниС TON для Ρ€Π΅ΠΊΠ»Π°ΠΌΡ‹ +ton_client = FragmentTon() +result = await ton_client.topup_ton("@username", 5) + +# ΠŸΠΎΠΊΡƒΠΏΠΊΠ° Premium +premium_client = FragmentPremium() +result = await premium_client.buy_premium("@username", 6) + +# ΠŸΠΎΠΊΡƒΠΏΠΊΠ° Stars +stars_client = FragmentStars() +result = await stars_client.buy_stars("@username", 50) +``` + +### ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ + +| ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ | ΠœΠ΅Ρ‚ΠΎΠ΄ | ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ | ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ | +| ------------------- | ------------------------------- | ---------------------------------- | ------------------- | +| **ПополнСниС TON** | `topup_ton(username, amount)` | Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, количСство TON | 1-1,000,000,000 TON | +| **ΠŸΠΎΠ΄Π°Ρ€ΠΎΠΊ Premium** | `buy_premium(username, months)` | Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ | 3, 6 ΠΈΠ»ΠΈ 12 мСсяцСв | +| **ΠŸΠΎΠΊΡƒΠΏΠΊΠ° Stars** | `buy_stars(username, amount)` | Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, количСство Stars | 50-1,000,000 Stars | + +### Π€ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ ΠΈΠΌΡ‘Π½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ + +ВсС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ ΠΈΠΌΡ‘Π½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ: + +- `@username` (с @) +- `username` (Π±Π΅Π· @) + +
+ +### Made with ❀️ by [@bohd4nx](https://t.me/bohd4nx) + +**ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ ⭐ этому Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΡŽ, Ссли ΠΎΠ½ оказался ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ!** + +
diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a8532c --- /dev/null +++ b/README.md @@ -0,0 +1,180 @@ +
+ + +

πŸ’Ž Fragment API by @bohd4nx

+ +

+ Automate TON topups, Telegram Premium purchases, and Stars transactions via Fragment.com +

+ +[Report Bug](https://github.com/bohd4nx/fragmentapi/issues) Β· [Request Feature](https://github.com/bohd4nx/fragmentapi/issues) Β· [**Donate TON**](https://app.tonkeeper.com/transfer/UQBUAa7KCx1ifmoEy6lF7j-822Dm_cE1j9SR7UWteu3jzukV) + +
+ +--- + +## ✨ Features + +- πŸ’° **TON Advertisement Topups** - Send TON for advertising campaigns and purchasing gifts (1-1,000,000,000 TON) +- πŸ‘‘ **Telegram Premium Gifts** - Purchase Premium subscriptions (3, 6, or 12 months) +- ⭐ **Telegram Stars Purchases** - Buy Stars for users (50-1,000,000 Stars) + +## πŸš€ Quick Start + +### 1. Installation + +```bash +git clone https://github.com/bohd4nx/FragmentAPI.git +cd FragmentAPI +pip install -r requirements.txt +``` + +### 2. Configuration + +Copy example configuration and edit: + +```bash +cp .env.example .env +``` + +Edit `.env` file: + +```env +COOKIES=your_fragment_cookies_here + +SEED=word1 word2 word3 ... word24 + +HASH=your_fragment_hash_here + +API_KEY=your_ton_api_key_here +``` + +### 3. Getting Required Data + +#### πŸͺ Fragment.com Cookies + +**Prerequisites**: Login to your Telegram account and connect the TON wallet you want to use for payments. + +1. **Install Cookie Editor Extension**: + + - Download from [Chrome Web Store](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) + - Add extension to your browser + +2. **Extract Cookies**: + - Open [Fragment.com](https://fragment.com) and ensure you're logged in + - Refresh the page completely + - Click on the Cookie Editor extension icon + - Click **"Export"** button + - Select **"Header String"** format + - Copy the result β†’ paste to `COOKIES` in your `.env` file + - **Important**: Wrap the value in quotes to prevent semicolons from being treated as comments + +**Expected format**: + +```env +COOKIES = "stel_token=;stel_dt=;stel_ssid=;stel_ton_token=" +``` + +#### πŸ” TON Wallet Seed Phrase + +**If you don't have a TON wallet yet**: + +1. **Download Tonkeeper**: + + - iOS: [App Store](https://apps.apple.com/app/tonkeeper/id1587742107) + - Android: [Google Play](https://play.google.com/store/apps/details?id=com.ton_keeper) + +2. **Create New Wallet**: + + - Open Tonkeeper app + - Tap **"Create New Wallet"** + - **IMPORTANT**: Write down your 24-word seed phrase on paper + - Store it securely - never share with anyone! + - Complete wallet setup + +3. **Get Your Seed Phrase**: + - If you already have a wallet, go to Settings β†’ Backup + - Enter your passcode + - Copy the 24 words β†’ paste to `SEED` in your `.env` file + +**Format**: `word1 word2 word3 ... word24` + +#### πŸ”— Fragment Hash + +**Prerequisites**: Complete the cookies setup above first. + +1. **Connect Wallet to Fragment**: + + - Go to [Fragment.com](https://fragment.com) + - Ensure your TON wallet is connected + - Log in with your Telegram account + +2. **Extract Hash**: + - Open **Developer Tools** (F12) + - Click on **"Network"** tab + - Navigate to [Fragment Stars Purchase](https://fragment.com/stars/buy) + - Select recipient as **"Buy for myself"** + - Refresh the page (Ctrl+R / Cmd+R) + - Look for network requests containing `?hash=` + - Find the hash value and copy it β†’ paste to `HASH` in your `.env` file + +**Expected format**: `?hash=` + +#### πŸ”‘ TON API Key + +1. **Get API Key**: + - Visit [TON Console](https://tonconsole.com) + - Create account and login + - Generate new API key + - Copy the key β†’ paste to `API_KEY` in your `.env` file + +**Alternative**: You can also use [TON API](https://tonapi.io) for getting API key. + +### 4. Usage + +#### Run Examples + +```bash +python main.py +``` + +#### Programmatic Usage + +```python +from app.methods import FragmentTon, FragmentPremium, FragmentStars + +# TON topup for ads +ton_client = FragmentTon() +result = await ton_client.topup_ton("@username", 5) + +# Premium purchase +premium_client = FragmentPremium() +result = await premium_client.buy_premium("@username", 6) + +# Stars purchase +stars_client = FragmentStars() +result = await stars_client.buy_stars("@username", 50) +``` + +### Supported Operations + +| Operation | Method | Parameters | Limits | +| ------------------ | ------------------------------- | ---------------------- | ------------------- | +| **TON Topup** | `topup_ton(username, amount)` | Username, TON amount | 1-1,000,000,000 TON | +| **Premium Gift** | `buy_premium(username, months)` | Username, duration | 3, 6, or 12 months | +| **Stars Purchase** | `buy_stars(username, amount)` | Username, Stars amount | 50-1,000,000 Stars | + +### Username Formats + +All methods accept various username formats: + +- `@username` (with @) +- `username` (without @) + +
+ +### Made with ❀️ by [@bohd4nx](https://t.me/bohd4nx) + +**Star ⭐ this repo if you found it useful!** + +
diff --git a/app/__meta__.py b/app/__meta__.py new file mode 100644 index 0000000..229198b --- /dev/null +++ b/app/__meta__.py @@ -0,0 +1,4 @@ +__title__ = "Fragment API by @bohd4nx" +__version__ = "2025.1.1" +__author__ = "Bohdan (bohd4nx)" +__timestamp__ = "2025-11-03T12:00:00Z" diff --git a/app/core/__init__.py b/app/core/__init__.py new file mode 100644 index 0000000..ac3258e --- /dev/null +++ b/app/core/__init__.py @@ -0,0 +1,3 @@ +from app.core.config import Config + +__all__ = ['Config'] diff --git a/app/core/config.py b/app/core/config.py new file mode 100644 index 0000000..be8ce34 --- /dev/null +++ b/app/core/config.py @@ -0,0 +1,37 @@ +import logging +import os +import sys +from typing import Dict + +from dotenv import load_dotenv + +load_dotenv(encoding='utf-8') + +logger = logging.getLogger(__name__) + + +class Config: + def __init__(self): + required_keys = ['COOKIES', 'SEED', 'HASH', 'API_KEY'] + missing_keys = [] + + self._config = {} + + for key in required_keys: + value = os.getenv(key, '').strip() + if not value: + missing_keys.append(key) + self._config[key.lower()] = value + + if missing_keys: + logger.error(f"Missing required environment variables: {', '.join(missing_keys)}") + logger.error("Create .env file based on .env.example and fill all fields") + sys.exit(1) + + logger.info("Configuration loaded successfully") + + def get_config(self) -> Dict[str, str]: + return self._config.copy() + + def get(self, key: str, default: str = '') -> str: + return self._config.get(key, default) diff --git a/app/methods/__init__.py b/app/methods/__init__.py new file mode 100644 index 0000000..fc72eef --- /dev/null +++ b/app/methods/__init__.py @@ -0,0 +1,5 @@ +from app.methods.premium import FragmentPremium +from app.methods.stars import FragmentStars +from app.methods.ton import FragmentTon + +__all__ = ['FragmentTon', 'FragmentPremium', 'FragmentStars'] diff --git a/app/methods/premium.py b/app/methods/premium.py new file mode 100644 index 0000000..27aefd9 --- /dev/null +++ b/app/methods/premium.py @@ -0,0 +1,120 @@ +import base64 +import logging +import re +import string +import time + +import httpx +from tonutils.client import TonapiClient +from tonutils.wallet import WalletV5R1 + +from app.core.config import Config +from app.utils import TransactionProcessor, WalletLinker, ApiClient + +logger = logging.getLogger(__name__) + + +class FragmentPremium: + def __init__(self): + config_reader = Config() + self.config = config_reader.get_config() + + self.headers = { + 'accept': 'application/json, text/javascript, */*; q=0.01', + 'accept-encoding': 'gzip, deflate, br, zstd', + 'accept-language': 'en-US,en;q=0.9,uk;q=0.8,ru;q=0.7', + 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'cookie': self.config['cookies'], + 'origin': 'https://fragment.com', + 'referer': 'https://fragment.com/premium/buy', + 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1', + 'x-requested-with': 'XMLHttpRequest' + } + + self.transaction_processor = TransactionProcessor(self.config, self._clean_decode) + self.wallet_linker = WalletLinker(self.config, self.headers, self.transaction_processor) + self.api_client = ApiClient(self.config, self.headers, self.wallet_linker) + + @staticmethod + def _clean_decode(s): + b = base64.b64decode(re.sub(r'[^A-Za-z0-9+/=]', '', s.strip()) + "=" * (-len(s) % 4)) + t = next( + (b[i:].decode('utf-8', 'ignore') for i in range(20) if + b[i:].decode('utf-8', 'ignore').startswith("Telegram Premium")), + b.decode('utf-8', 'ignore') + ) + return ''.join(c for c in t if c in string.printable or c in '\n\r\t ').strip() + + async def _get_account_info(self): + client = TonapiClient(api_key=self.config['api_key'], is_testnet=False) + wallet, pub_key, _, _ = WalletV5R1.from_mnemonic(client=client, mnemonic=self.config['seed']) + boc = wallet.state_init.serialize().to_boc() + + return { + "address": wallet.address.to_str(False, False), + "publicKey": pub_key.hex(), + "chain": "-239", + "walletStateInit": base64.b64encode(boc).decode() + } + + async def buy_premium(self, username, months): + if months not in [3, 6, 12]: + return {"success": False, "error": "Invalid duration. Use 3, 6, or 12 months"} + + account = await self._get_account_info() + + async with httpx.AsyncClient() as client: + search_data = {"query": username, "months": months, "method": "searchPremiumGiftRecipient"} + search_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=search_data) + search_result = search_resp.json() + + recipient = search_result.get("found", {}).get("recipient") + if not recipient: + return {"success": False, "error": "User not found"} + + update_data = {"mode": "new", "lv": "false", "dh": str(int(time.time())), "method": "updatePremiumState"} + await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=update_data) + + init_data = {"recipient": recipient, "months": months, "method": "initGiftPremiumRequest"} + init_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=init_data) + init_result = init_resp.json() + + req_id = init_result.get("req_id") + if not req_id: + return {"success": False, "error": "Failed to initialize purchase"} + + tx_data = { + 'account': account, + 'device': {"appVersion": "5.4.3", "platform": "iphone", + "features": ["SendTransaction", {"maxMessages": 255, "name": "SendTransaction"}, + {"types": ["text", "binary", "cell"], "name": "SignData"}], + "appName": "Tonkeeper", "maxProtocolVersion": 2}, + 'transaction': 1, + 'id': req_id, + 'show_sender': 1, + 'ref': "OprzztcdJ", + 'method': 'getGiftPremiumLink' + } + + request_success, transaction_result = await self.api_client.execute_transaction_request(tx_data, account) + + if not request_success: + return transaction_result + + success, error, tx_hash = await self.transaction_processor.process_transaction(transaction_result) + + if success: + return { + "success": True, + "data": { + "transaction_id": tx_hash, + "username": username, + "months": months, + "timestamp": int(time.time()) + } + } + + return {"success": False, "error": error} diff --git a/app/methods/stars.py b/app/methods/stars.py new file mode 100644 index 0000000..13feed4 --- /dev/null +++ b/app/methods/stars.py @@ -0,0 +1,109 @@ +import base64 +import logging +import re +import time + +import httpx +from tonutils.client import TonapiClient +from tonutils.wallet import WalletV5R1 + +from app.core.config import Config +from app.utils import TransactionProcessor, WalletLinker, ApiClient + +logger = logging.getLogger(__name__) + + +class FragmentStars: + def __init__(self): + config_reader = Config() + self.config = config_reader.get_config() + + self.headers = { + 'accept': 'application/json, text/javascript, */*; q=0.01', + 'accept-encoding': 'gzip, deflate, br, zstd', + 'accept-language': 'en-US,en;q=0.9,uk;q=0.8,ru;q=0.7', + 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'cookie': self.config['cookies'], + 'origin': 'https://fragment.com', + 'referer': 'https://fragment.com/stars/buy', + 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1', + 'x-requested-with': 'XMLHttpRequest' + } + + self.transaction_processor = TransactionProcessor(self.config, self._clean_decode) + self.wallet_linker = WalletLinker(self.config, self.headers, self.transaction_processor) + self.api_client = ApiClient(self.config, self.headers, self.wallet_linker) + + @staticmethod + def _clean_decode(s): + s = re.sub(r'[^A-Za-z0-9+/=]', '', s.strip()) + b = base64.b64decode(s + "=" * (-len(s) % 4)) + t = b.decode('utf-8', 'ignore') + m = re.search(r'(\d+\s+Telegram\s+Stars.*?Ref#[A-Za-z0-9]+)', t, re.S) + return m.group(1).strip() if m else t.strip() + + async def _get_account_info(self): + client = TonapiClient(api_key=self.config['api_key'], is_testnet=False) + wallet, pub_key, _, _ = WalletV5R1.from_mnemonic(client=client, mnemonic=self.config['seed']) + boc = wallet.state_init.serialize().to_boc() + + return { + "address": wallet.address.to_str(False, False), + "publicKey": pub_key.hex(), + "chain": "-239", + "walletStateInit": base64.b64encode(boc).decode() + } + + async def buy_stars(self, username, amount): + if amount < 50: + return {"success": False, "error": "Minimum amount is 50 stars"} + + account = await self._get_account_info() + + async with httpx.AsyncClient() as client: + search_data = {"query": username, "quantity": "", "method": "searchStarsRecipient"} + search_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=search_data) + search_result = search_resp.json() + + recipient = search_result.get("found", {}).get("recipient") + if not recipient: + return {"success": False, "error": "User not found"} + + init_data = {"recipient": recipient, "quantity": amount, "method": "initBuyStarsRequest"} + init_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=init_data) + init_result = init_resp.json() + + req_id = init_result.get("req_id") + if not req_id: + return {"success": False, "error": "Failed to initialize purchase"} + + tx_data = { + 'account': account, + 'device': "iPhone15,2", + 'transaction': 1, + 'id': req_id, + 'show_sender': 0, + 'method': 'getBuyStarsLink' + } + + request_success, transaction_result = await self.api_client.execute_transaction_request(tx_data, account) + + if not request_success: + return transaction_result + + success, error, tx_hash = await self.transaction_processor.process_transaction(transaction_result) + + if success: + return { + "success": True, + "data": { + "transaction_id": tx_hash, + "username": username, + "amount": amount, + "timestamp": int(time.time()) + } + } + + return {"success": False, "error": error} diff --git a/app/methods/ton.py b/app/methods/ton.py new file mode 100644 index 0000000..8467ff8 --- /dev/null +++ b/app/methods/ton.py @@ -0,0 +1,115 @@ +import base64 +import logging +import re +import time + +import httpx +from tonutils.client import TonapiClient +from tonutils.wallet import WalletV5R1 + +from app.core.config import Config +from app.utils import TransactionProcessor, WalletLinker, ApiClient + +logger = logging.getLogger(__name__) + + +class FragmentTon: + def __init__(self): + config_reader = Config() + self.config = config_reader.get_config() + + self.headers = { + 'accept': 'application/json, text/javascript, */*; q=0.01', + 'accept-encoding': 'gzip, deflate, br, zstd', + 'accept-language': 'en-US,en;q=0.9,uk;q=0.8,ru;q=0.7', + 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'cookie': self.config['cookies'], + 'origin': 'https://fragment.com', + 'referer': 'https://fragment.com/ads/topup', + 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1', + 'x-requested-with': 'XMLHttpRequest' + } + + self.transaction_processor = TransactionProcessor(self.config, self._clean_decode) + self.wallet_linker = WalletLinker(self.config, self.headers, self.transaction_processor) + self.api_client = ApiClient(self.config, self.headers, self.wallet_linker) + + @staticmethod + def _clean_decode(s): + t = base64.b64decode(re.sub(r'[^A-Za-z0-9+/=]', '', s.strip()) + "=" * (-len(s) % 4)).decode('utf-8', + errors='ignore') + t = ''.join(c for c in t if c.isprintable() or c.isspace()) + return t.lstrip("r0N").strip() + + async def _get_account_info(self): + client = TonapiClient(api_key=self.config['api_key'], is_testnet=False) + wallet, pub_key, _, _ = WalletV5R1.from_mnemonic(client=client, mnemonic=self.config['seed']) + boc = wallet.state_init.serialize().to_boc() + + return { + "address": wallet.address.to_str(False, False), + "publicKey": pub_key.hex(), + "chain": "-239", + "walletStateInit": base64.b64encode(boc).decode() + } + + async def topup_ton(self, username, amount): + if amount < 1 or not isinstance(amount, int): + return {"success": False, "error": "Amount must be an integer >= 1 TON"} + + account = await self._get_account_info() + + async with httpx.AsyncClient() as client: + update_data = {"mode": "new", "method": "updateAdsTopupState"} + await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=update_data) + + search_data = {"query": username, "method": "searchAdsTopupRecipient"} + search_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=search_data) + search_result = search_resp.json() + + recipient = search_result.get("found", {}).get("recipient") + if not recipient: + return {"success": False, "error": "User not found"} + + init_data = {"recipient": recipient, "amount": amount, "method": "initAdsTopupRequest"} + init_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=init_data) + init_result = init_resp.json() + + req_id = init_result.get("req_id") + if not req_id: + return {"success": False, "error": "Failed to initialize topup"} + + tx_data = { + 'account': account, + 'device': {"appVersion": "5.4.3", "platform": "iphone", + "features": ["SendTransaction", {"maxMessages": 255, "name": "SendTransaction"}, + {"types": ["text", "binary", "cell"], "name": "SignData"}], + "appName": "Tonkeeper", "maxProtocolVersion": 2}, + 'transaction': 1, + 'id': req_id, + 'show_sender': 1, + 'method': 'getAdsTopupLink' + } + + request_success, transaction_result = await self.api_client.execute_transaction_request(tx_data, account) + + if not request_success: + return transaction_result + + success, error, tx_hash = await self.transaction_processor.process_transaction(transaction_result) + + if success: + return { + "success": True, + "data": { + "transaction_id": tx_hash, + "username": username, + "amount": amount, + "timestamp": int(time.time()) + } + } + + return {"success": False, "error": error} diff --git a/app/utils/__init__.py b/app/utils/__init__.py new file mode 100644 index 0000000..a053fc8 --- /dev/null +++ b/app/utils/__init__.py @@ -0,0 +1,5 @@ +from .api_client import ApiClient +from .linkWallet import WalletLinker +from .transaction import TransactionProcessor + +__all__ = ['TransactionProcessor', 'WalletLinker', 'ApiClient'] diff --git a/app/utils/api_client.py b/app/utils/api_client.py new file mode 100644 index 0000000..3c39164 --- /dev/null +++ b/app/utils/api_client.py @@ -0,0 +1,27 @@ +from typing import Dict, Any, Tuple + +import httpx + + +class ApiClient: + def __init__(self, config: dict, headers: dict, wallet_linker): + self.config = config + self.headers = headers + self.wallet_linker = wallet_linker + + async def execute_transaction_request(self, tx_data: Dict[str, Any], account: Dict[str, Any]) -> Tuple[ + bool, Dict[str, Any]]: + async with httpx.AsyncClient() as client: + tx_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=tx_data) + transaction = tx_resp.json() + + if transaction.get("need_verify"): + if not await self.wallet_linker.link_wallet(account): + return False, {"success": False, "error": "Failed to link wallet"} + + tx_resp = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=tx_data) + transaction = tx_resp.json() + + return True, transaction diff --git a/app/utils/linkWallet.py b/app/utils/linkWallet.py new file mode 100644 index 0000000..68ed0c3 --- /dev/null +++ b/app/utils/linkWallet.py @@ -0,0 +1,31 @@ +from typing import Dict, Any + +import httpx + + +class WalletLinker: + def __init__(self, config: dict, headers: dict, transaction_processor): + self.config = config + self.headers = headers + self.transaction_processor = transaction_processor + + async def link_wallet(self, account: Dict[str, Any]) -> bool: + async with httpx.AsyncClient() as client: + data = { + 'account': account, + 'device': "iPhone15,2", + 'method': 'linkWallet' + } + + response = await client.post(f"https://fragment.com/api?hash={self.config['hash']}", + headers=self.headers, data=data) + result = response.json() + + if result.get("ok"): + return True + + if "transaction" in result: + success, _, _ = await self.transaction_processor.process_transaction(result) + return success + + return False diff --git a/app/utils/transaction.py b/app/utils/transaction.py new file mode 100644 index 0000000..764a0b5 --- /dev/null +++ b/app/utils/transaction.py @@ -0,0 +1,36 @@ +import logging +from typing import Tuple, Optional + +from tonutils.client import TonapiClient +from tonutils.wallet import WalletV5R1 +from tonutils.wallet.messages import TransferMessage + +logger = logging.getLogger(__name__) + + +class TransactionProcessor: + def __init__(self, config: dict, clean_decode_func): + self.config = config + self._clean_decode = clean_decode_func + + async def process_transaction(self, transaction_data: dict) -> Tuple[bool, Optional[str], Optional[str]]: + if "transaction" not in transaction_data or "messages" not in transaction_data["transaction"]: + return False, "Invalid transaction", None + + client = TonapiClient(api_key=self.config['api_key'], is_testnet=False) + wallet, _, _, _ = WalletV5R1.from_mnemonic(client=client, mnemonic=self.config['seed']) + + try: + message = transaction_data["transaction"]["messages"][0] + payload = self._clean_decode(message["payload"]) + + messages = [TransferMessage( + destination=message["address"], + amount=int(message["amount"]) / 1000000000, + body=payload + )] + + tx_hash = await wallet.batch_transfer_messages(messages=messages) + return True, None, tx_hash + except Exception as e: + return False, str(e), None diff --git a/main.py b/main.py new file mode 100644 index 0000000..0774b4d --- /dev/null +++ b/main.py @@ -0,0 +1,71 @@ +import asyncio +import logging + +from app.methods import FragmentTon, FragmentPremium, FragmentStars + +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logger = logging.getLogger(__name__) + + +async def topup_ton_example(): + logger.info("Starting TON topup example") + + ton_client = FragmentTon() + # @bohd4nx - target username, 5 - TON amount (integer 1-1000000000 (one billion)) + result = await ton_client.topup_ton("@bohd4nx", 5) + + if result["success"]: + data = result["data"] + logger.info(f"TON topup successful: {data['amount']} TON sent to {data['username']}") + logger.info(f"Transaction ID: {data['transaction_id']}") + else: + logger.error(f"TON topup failed: {result['error']}") + + +async def buy_premium_example(): + logger.info("Starting Premium purchase example") + + premium_client = FragmentPremium() + # @bohd4nx - target username, 6 - months duration (3, 6, or 12 only) + result = await premium_client.buy_premium("@bohd4nx", 6) + + if result["success"]: + data = result["data"] + logger.info(f"Premium purchase successful: {data['months']} months sent to {data['username']}") + logger.info(f"Transaction ID: {data['transaction_id']}") + else: + logger.error(f"Premium purchase failed: {result['error']}") + + +async def buy_stars_example(): + logger.info("Starting Stars purchase example") + + stars_client = FragmentStars() + # @bohd4nx - target username, 50 - stars amount (integer 50-1000000 (one million)) + result = await stars_client.buy_stars("@bohd4nx", 50) + + if result["success"]: + data = result["data"] + logger.info(f"Stars purchase successful: {data['amount']} stars sent to {data['username']}") + logger.info(f"Transaction ID: {data['transaction_id']}") + else: + logger.error(f"Stars purchase failed: {result['error']}") + + +async def main(): + logger.info("Starting Fragment API by @bohd4nx - examples") + + await topup_ton_example() + await buy_premium_example() + await buy_stars_example() + + logger.info("All examples completed") + + +if __name__ == "__main__": + logger.info("Fragment API by @bohd4nx - Usage Examples") + logger.info("Supported username formats: @username, username") + logger.info("Limits: TON minimum 1, Premium 3/6/12 months, Stars minimum 50") + logger.info("Setup: Copy .env.example to .env and fill all fields") + + asyncio.run(main()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..cafc9e5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +python-dotenv==1.2.1 +asyncio==4.0.0 +httpx==0.28.1 +tonutils==0.5.3 \ No newline at end of file