mirror of
https://github.com/vibe-existing/pyfragment.git
synced 2026-07-25 06:54:31 +00:00
3e14a01c92
- Security & validation: tighten hash regex, add HTTP timeouts to all requests, pass client.timeout through get_fragment_hash and AsyncClient - Constants: move all constants to types/constants.py; remove re-exports from types/__init__.py; add DEFAULT_TIMEOUT, REQUIRED_COOKIE_KEYS - FragmentClient: add timeout param (default 30 s); async-context-manager support; remove WALLET_CLASSES from public API - Exceptions: remove dead INVALID_USERNAME constant (Fragment validates server-side); keep full hierarchy intact - Tests: add 006_test_methods_mock.py (6 mock tests for all 3 methods); DRY-refactor 004_test_balance.py (_patch_wallet context manager); clean up 005_test_methods.py (remove fragile network test, rename tests) - Examples: switch all 4 examples to async-with; align error messages; replace %-format with f-strings - README: rewrite usage section with single comprehensive async-with example covering all 3 methods and full exception hierarchy - CI: add mypy step to lint job; add pytest-mock and mypy to dev deps; set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 on all jobs; fix COOKIES_JSON to job-level env var
127 lines
5.5 KiB
Markdown
127 lines
5.5 KiB
Markdown
<div align="center">
|
||
<img src="fragment.svg" alt="Fragment Logo" width="120" height="120" style="border-radius: 24px;">
|
||
|
||
<h1 style="margin-top: 24px;">Fragment API</h1>
|
||
|
||
<p style="font-size: 18px; margin-bottom: 24px;">
|
||
<b>Python library for the Fragment.com API — purchase Telegram Stars, Premium, and top up TON Ads balance.</b>
|
||
</p>
|
||
|
||
[](https://pypi.org/project/pyfragment/)
|
||
[](https://pypi.org/project/pyfragment/)
|
||
[](https://python.org)
|
||
[](LICENSE)
|
||
[](https://github.com/bohd4nx/pyfragment/stargazers)
|
||
[](https://github.com/bohd4nx/pyfragment/actions)
|
||
|
||
[Report Bug](https://github.com/bohd4nx/pyfragment/issues) · [Request Feature](https://github.com/bohd4nx/pyfragment/issues) · [**Donate TON**](https://app.tonkeeper.com/transfer/UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5)
|
||
|
||
</div>
|
||
|
||
> **Disclaimer:** This project is not affiliated with, endorsed by, or in any way officially connected with [Fragment](https://fragment.com) or [Telegram](https://telegram.org).
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
pip install pyfragment
|
||
```
|
||
|
||
Requires Python 3.12+.
|
||
|
||
---
|
||
|
||
## Configuration
|
||
|
||
| Parameter | Type | Default | Description |
|
||
| ---------------- | ------------- | -------- | -------------------------------------------------------- |
|
||
| `seed` | `str` | — | 24-word TON wallet mnemonic |
|
||
| `api_key` | `str` | — | Tonapi key from [tonconsole.com](https://tonconsole.com) |
|
||
| `cookies` | `dict \| str` | — | Fragment session cookies |
|
||
| `wallet_version` | `str` | `"V5R1"` | `"V4R2"` or `"V5R1"` |
|
||
| `timeout` | `float` | `30.0` | HTTP request timeout in seconds |
|
||
|
||
---
|
||
|
||
## Credentials
|
||
|
||
**Fragment cookies** — log in to [fragment.com](https://fragment.com), install [Cookie Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm), and export these four keys: `stel_ssid`, `stel_dt`, `stel_token`, `stel_ton_token`. Pass them as a `dict` or as a JSON string. Refresh when you get authentication errors.
|
||
|
||
**Tonapi key** — generate at [tonconsole.com](https://tonconsole.com).
|
||
|
||
**Seed phrase** — 24-word mnemonic from your TON wallet (Tonkeeper → Settings → Backup). Never share it.
|
||
|
||
---
|
||
|
||
## Usage
|
||
|
||
```python
|
||
import asyncio
|
||
from pyfragment import (
|
||
FragmentClient,
|
||
FragmentError, # base — catches everything below
|
||
UserNotFoundError, # username doesn't exist on Fragment
|
||
WalletError, # insufficient balance or misconfiguration
|
||
CookieError, # cookies are missing or expired
|
||
TransactionError, # on-chain broadcast failed
|
||
ConfigurationError, # invalid argument (months, amount, etc.)
|
||
FragmentAPIError, # unexpected Fragment API response
|
||
)
|
||
|
||
|
||
async def main() -> None:
|
||
async with FragmentClient(
|
||
seed="word1 word2 ... word24", # 24-word TON wallet mnemonic
|
||
api_key="YOUR_TONAPI_KEY", # from tonconsole.com
|
||
cookies={
|
||
"stel_ssid": "...",
|
||
"stel_dt": "...",
|
||
"stel_token": "...",
|
||
"stel_ton_token": "...",
|
||
},
|
||
) as client:
|
||
try:
|
||
# Purchase 6 months of Telegram Premium for a user
|
||
result = await client.purchase_premium("@username", months=6)
|
||
print(f"{result.months} months of Premium successfully sent to {result.username} | tx: {result.transaction_id}")
|
||
|
||
# Purchase 500 Stars for a user (50–1 000 000)
|
||
result = await client.purchase_stars("@username", amount=500)
|
||
print(f"{result.stars} Stars successfully sent to {result.username} | tx: {result.transaction_id}")
|
||
|
||
# Top up 10 TON to Telegram Ads balance
|
||
# wallet must hold at least amount + ~0.056 TON for gas
|
||
result = await client.topup_ton("@username", amount=10)
|
||
print(f"{result.amount} TON successfully sent to {result.username} | tx: {result.transaction_id}")
|
||
|
||
except UserNotFoundError:
|
||
print(f"User was not found on fragment.com — check the username and try again.")
|
||
except WalletError as e:
|
||
print(f"Wallet error — insufficient balance or misconfiguration: {e}")
|
||
except CookieError:
|
||
print("Authentication failed — session cookies are missing or expired. Refresh them and retry.")
|
||
except TransactionError as e:
|
||
print(f"Transaction failed to broadcast on-chain: {e}")
|
||
except ConfigurationError as e:
|
||
print(f"Invalid argument: {e}")
|
||
except FragmentAPIError as e:
|
||
print(f"Unexpected response from Fragment API: {e}")
|
||
except FragmentError as e:
|
||
# catch-all for any other pyfragment error
|
||
print(f"Unexpected error: {e}")
|
||
|
||
|
||
asyncio.run(main())
|
||
```
|
||
|
||
---
|
||
|
||
<div align="center">
|
||
|
||
### Made with ❤️ by [@bohd4nx](https://t.me/bohd4nx)
|
||
|
||
**Star ⭐ this repo if you found it useful!**
|
||
|
||
</div>
|