diff --git a/CHANGELOG.md b/CHANGELOG.md index 48134f1..64b5ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,8 @@ and this project uses [Calendar Versioning](https://calver.org/) (`YYYY.MINOR.MI ### Added - Initial stable release of `pyfragment` - `FragmentClient` — async client for the Fragment.com API -- `gift_premium(username, months)` — purchase Telegram Premium for any user (3, 6, or 12 months) -- `gift_stars(username, amount)` — send Telegram Stars to any user (50–1,000,000) +- `purchase_premium(username, months)` — purchase Telegram Premium for any user (3, 6, or 12 months) +- `purchase_stars(username, amount)` — send Telegram Stars to any user (50–1,000,000) - `topup_ton(username, amount)` — top up TON Ads balance (1–1,000,000,000 TON) - `get_wallet()` — fetch wallet address and balance - Support for TON wallet versions `V4R2` and `V5R1` diff --git a/README.md b/README.md index 5ae7d3d..9bb94ce 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,11 @@ client = FragmentClient( async def main(): # Purchase 6 months of Telegram Premium - result = await client.gift_premium("@username", months=6) + result = await client.purchase_premium("@username", months=6) print(result.transaction_id) # Purchase 500 Stars - result = await client.gift_stars("@username", amount=500) + result = await client.purchase_stars("@username", amount=500) print(result.transaction_id) # Top up 10 TON to Ads balance @@ -96,8 +96,8 @@ See the [`examples/`](examples/) folder for ready-to-run scripts. | Method | Returns | Description | Limits | | -------------------------------------------------- | ---------------- | ---------------------------------- | ------------------------- | -| `gift_premium(username, months, show_sender=True)` | `PremiumResult` | Purchase Telegram Premium | `months`: 3, 6, or 12 | -| `gift_stars(username, amount, show_sender=True)` | `StarsResult` | Purchase Telegram Stars | `amount`: 50–1,000,000 | +| `purchase_premium(username, months, show_sender=True)` | `PremiumResult` | Purchase Telegram Premium | `months`: 3, 6, or 12 | +| `purchase_stars(username, amount, show_sender=True)` | `StarsResult` | Purchase Telegram Stars | `amount`: 50–1,000,000 | | `topup_ton(username, amount, show_sender=True)` | `AdsTopupResult` | Top up Telegram Ads balance | `amount`: 1–1,000,000,000 | | `get_wallet()` | `WalletInfo` | Get wallet address, state, balance | — | @@ -111,7 +111,7 @@ See the [`examples/`](examples/) folder for ready-to-run scripts. 1. Install [Cookie Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) 2. Open [fragment.com](https://fragment.com) while logged in -3. Click the extension → **Export** → **JSON** +3. Click the extension → **Export** → **Header String** 4. Extract these four fields: ```json @@ -155,7 +155,7 @@ All exceptions inherit from `FragmentError` — see [`pyfragment/types/exception from pyfragment import FragmentClient, UserNotFoundError, ConfigurationError, WalletError try: - result = await client.gift_stars("@unknown", amount=100) + result = await client.purchase_stars("@unknown", amount=100) except UserNotFoundError: print("User not found on Fragment") except WalletError as e: diff --git a/examples/purchase_premium.py b/examples/purchase_premium.py index 16b8395..d4366f2 100644 --- a/examples/purchase_premium.py +++ b/examples/purchase_premium.py @@ -26,7 +26,7 @@ async def main() -> None: client = FragmentClient(seed=SEED, api_key=API_KEY, cookies=COOKIES) try: - result = await client.gift_premium(USERNAME, months=MONTHS, show_sender=True) + result = await client.purchase_premium(USERNAME, months=MONTHS, show_sender=True) except UserNotFoundError: print(f"User {USERNAME!r} not found on Fragment.") return diff --git a/examples/purchase_stars.py b/examples/purchase_stars.py index e9500b9..c0902a4 100644 --- a/examples/purchase_stars.py +++ b/examples/purchase_stars.py @@ -26,7 +26,7 @@ async def main() -> None: client = FragmentClient(seed=SEED, api_key=API_KEY, cookies=COOKIES) try: - result = await client.gift_stars(USERNAME, amount=AMOUNT, show_sender=True) + result = await client.purchase_stars(USERNAME, amount=AMOUNT, show_sender=True) except UserNotFoundError: print(f"User {USERNAME!r} not found on Fragment.") return diff --git a/pyfragment/client.py b/pyfragment/client.py index 0c33fce..3927e0d 100644 --- a/pyfragment/client.py +++ b/pyfragment/client.py @@ -1,7 +1,7 @@ import json -from pyfragment.methods.premium import gift_premium -from pyfragment.methods.stars import gift_stars +from pyfragment.methods.premium import purchase_premium +from pyfragment.methods.stars import purchase_stars from pyfragment.methods.ton import topup_ton from pyfragment.types import ( REQUIRED_COOKIE_KEYS, @@ -43,7 +43,7 @@ class FragmentClient: cookies={"stel_ssid": "...", "stel_dt": "...", ...}, ) print(await client.get_wallet()) - result = await client.gift_premium("@username", months=6) + result = await client.purchase_premium("@username", months=6) print(result.transaction_id) """ @@ -88,7 +88,7 @@ class FragmentClient: self.cookies: dict = cookies self.wallet_version: WalletVersion = version # type: ignore[assignment] - async def gift_premium(self, username: str, months: int, show_sender: bool = True) -> PremiumResult: + async def purchase_premium(self, username: str, months: int, show_sender: bool = True) -> PremiumResult: """Purchase Telegram Premium for a user. Args: @@ -99,9 +99,9 @@ class FragmentClient: Returns: :class:`PremiumResult` with ``transaction_id``, ``username``, ``months``, ``timestamp``. """ - return await gift_premium(self, username, months, show_sender) + return await purchase_premium(self, username, months, show_sender) - async def gift_stars(self, username: str, amount: int, show_sender: bool = True) -> StarsResult: + async def purchase_stars(self, username: str, amount: int, show_sender: bool = True) -> StarsResult: """Purchase Telegram Stars for a user. Args: @@ -112,7 +112,7 @@ class FragmentClient: Returns: :class:`StarsResult` with ``transaction_id``, ``username``, ``stars``, ``timestamp``. """ - return await gift_stars(self, username, amount, show_sender) + return await purchase_stars(self, username, amount, show_sender) async def topup_ton(self, username: str, amount: int, show_sender: bool = True) -> AdsTopupResult: """Top up Telegram Ads balance with TON. diff --git a/pyfragment/methods/__init__.py b/pyfragment/methods/__init__.py index 82da1b2..c0f4e2e 100644 --- a/pyfragment/methods/__init__.py +++ b/pyfragment/methods/__init__.py @@ -1,5 +1,5 @@ -from pyfragment.methods.premium import gift_premium -from pyfragment.methods.stars import gift_stars +from pyfragment.methods.premium import purchase_premium +from pyfragment.methods.stars import purchase_stars from pyfragment.methods.ton import topup_ton -__all__ = ["gift_premium", "gift_stars", "topup_ton"] +__all__ = ["purchase_premium", "purchase_stars", "topup_ton"] diff --git a/pyfragment/methods/premium.py b/pyfragment/methods/premium.py index 5338227..0c19c6b 100644 --- a/pyfragment/methods/premium.py +++ b/pyfragment/methods/premium.py @@ -89,7 +89,7 @@ async def _init_request( return req_id -async def gift_premium(client: "FragmentClient", username: str, months: int, show_sender: bool = True) -> PremiumResult: +async def purchase_premium(client: "FragmentClient", username: str, months: int, show_sender: bool = True) -> PremiumResult: if months not in (3, 6, 12): raise ConfigurationError(ConfigurationError.INVALID_MONTHS) diff --git a/pyfragment/methods/stars.py b/pyfragment/methods/stars.py index c605e8d..bc58fa8 100644 --- a/pyfragment/methods/stars.py +++ b/pyfragment/methods/stars.py @@ -76,7 +76,7 @@ async def _init_request( return req_id -async def gift_stars(client: "FragmentClient", username: str, amount: int, show_sender: bool = True) -> StarsResult: +async def purchase_stars(client: "FragmentClient", username: str, amount: int, show_sender: bool = True) -> StarsResult: if not isinstance(amount, int) or not (50 <= amount <= 1_000_000): raise ConfigurationError(ConfigurationError.INVALID_STARS_AMOUNT) diff --git a/pyfragment/types/results.py b/pyfragment/types/results.py index 55d4add..a6ad138 100644 --- a/pyfragment/types/results.py +++ b/pyfragment/types/results.py @@ -12,6 +12,9 @@ class WalletInfo: state: str balance: float + def __repr__(self) -> str: + return f"WalletInfo(address='{self.address}', state='{self.state}', balance={self.balance} TON)" + @dataclass class PremiumResult: @@ -22,6 +25,9 @@ class PremiumResult: months: int timestamp: int = field(default_factory=lambda: int(time.time())) + def __repr__(self) -> str: + return f"PremiumResult(username='{self.username}', months={self.months}, tx='{self.transaction_id}')" + @dataclass class StarsResult: @@ -32,6 +38,9 @@ class StarsResult: stars: int timestamp: int = field(default_factory=lambda: int(time.time())) + def __repr__(self) -> str: + return f"StarsResult(username='{self.username}', stars={self.stars}, tx='{self.transaction_id}')" + @dataclass class AdsTopupResult: @@ -41,3 +50,6 @@ class AdsTopupResult: username: str amount: int timestamp: int = field(default_factory=lambda: int(time.time())) + + def __repr__(self) -> str: + return f"AdsTopupResult(username='{self.username}', amount={self.amount} TON, tx='{self.transaction_id}')"