diff --git a/CHANGELOG.md b/CHANGELOG.md index 9421ab6..5987e73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,12 @@ and this project uses [Calendar Versioning](https://calver.org/) (`YYYY.MINOR.MI --- -## [2026.3.2] — 2026-05-29 +## [2026.3.2] — Unreleased ### Added -- New payment methods for purchases and giveaways: `usdt_eth`, `usdt_pol`, `usdc_eth`, `usdc_base`, `usdc_pol`. - New `AlreadySubscribedError` exception for Premium purchase flows when Fragment returns: `This account is already subscribed to Telegram Premium.` +- New `UserNotFoundError.NOT_A_USER` message for when Fragment returns: `Please enter a username assigned to a user.` (e.g. when the username belongs to a channel or bot). ### Changed diff --git a/README.md b/README.md index 95ee4b5..5d8fdb9 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ pip install git+https://github.com/bohd4nx/pyfragment.git@dev ```python import asyncio from pyfragment import FragmentClient - +from pyfragment.models.enums import PaymentMethod async def main() -> None: async with FragmentClient( @@ -57,10 +57,17 @@ async def main() -> None: recipient = "https://t.me/username" # also: @username, username - stars = await client.purchase_stars(recipient, amount=500, payment_method="usdt_ton") - print(f"Sent {stars.amount} Stars to {stars.username} | tx: {stars.transaction_id}") + stars = await client.purchase_stars(recipient, amount=500, payment_method=PaymentMethod.USDT_TON) + if stars.auto_paid: + print(f"Sent {stars.amount} Stars to {stars.username} | tx: {stars.transaction_id}") + else: + print(f"Manual payment required for {stars.username}") + print(f"Address: {stars.payment_address}") + print(f"Amount: {stars.payment_amount}") + print(f"Expires: {stars.payment_expires_at}") + print(f"QR link: {stars.payment_qr_link}") - premium = await client.purchase_premium(recipient, months=6, payment_method="ton") + premium = await client.purchase_premium(recipient, months=6, payment_method=PaymentMethod.TON) print(f"Sent Premium {premium.amount}m to {premium.username} | tx: {premium.transaction_id}") diff --git a/pyfragment/domains/purchases/purchase.py b/pyfragment/domains/purchases/purchase.py index 20a8b4d..8449dc6 100644 --- a/pyfragment/domains/purchases/purchase.py +++ b/pyfragment/domains/purchases/purchase.py @@ -59,6 +59,8 @@ async def purchase_stars( try: result = await client.call("searchStarsRecipient", {"query": username, "quantity": ""}, page_url=STARS_PAGE) + if "assigned to a user" in str(result.get("error", "")).lower(): + raise UserNotFoundError(UserNotFoundError.NOT_A_USER.format(username=username)) recipient = result.get("found", {}).get("recipient") if not recipient: raise UserNotFoundError(UserNotFoundError.NOT_FOUND.format(username=username)) @@ -140,6 +142,8 @@ async def purchase_premium( try: result = await client.call("searchPremiumGiftRecipient", {"query": username, "months": months}, page_url=PREMIUM_PAGE) + if "assigned to a user" in str(result.get("error", "")).lower(): + raise UserNotFoundError(UserNotFoundError.NOT_A_USER.format(username=username)) recipient = result.get("found", {}).get("recipient") if not recipient: raise UserNotFoundError(UserNotFoundError.NOT_FOUND.format(username=username)) diff --git a/pyfragment/exceptions.py b/pyfragment/exceptions.py index 2b98d64..898396c 100644 --- a/pyfragment/exceptions.py +++ b/pyfragment/exceptions.py @@ -94,6 +94,7 @@ class UserNotFoundError(FragmentAPIError): NOT_FOUND = ( "Telegram user '{username}' was not found on Fragment. Double-check the username and make sure the account exists." ) + NOT_A_USER = "'{username}' does not belong to a user account. Make sure the username is assigned to a personal Telegram account, not a channel or bot." class AlreadySubscribedError(FragmentAPIError): diff --git a/pyfragment/models/enums.py b/pyfragment/models/enums.py index b9794b2..02b21ab 100644 --- a/pyfragment/models/enums.py +++ b/pyfragment/models/enums.py @@ -17,6 +17,8 @@ else: class PaymentMethod(StrEnum): TON = "ton" USDT_TON = "usdt_ton" + + # Not supported yet USDT_ETH = "usdt_eth" USDT_POL = "usdt_pol" USDC_ETH = "usdc_eth"