feat: update constants and validation for stars and payment methods; refactor enums for clarity

This commit is contained in:
bohd4nx
2026-05-29 22:11:03 +03:00
parent 5c472b68a2
commit 66bcd22198
7 changed files with 62 additions and 45 deletions
+5 -4
View File
@@ -1,7 +1,7 @@
from __future__ import annotations
import json
from typing import Any, cast, get_args
from typing import Any, cast
from pyfragment.core.constants import DEFAULT_TIMEOUT, FRAGMENT_BASE_URL, REQUIRED_COOKIE_KEYS
from pyfragment.domains.ads.service import AdsService
@@ -82,13 +82,14 @@ class FragmentClient:
@staticmethod
def _normalize_wallet_version(wallet_version: str) -> WalletVersion:
version = wallet_version.strip().upper()
if version not in get_args(WalletVersion):
try:
return WalletVersion(version)
except ValueError:
raise ConfigurationError(
ConfigurationError.UNSUPPORTED_VERSION.format(
version=version, supported=", ".join(sorted(get_args(WalletVersion)))
version=version, supported=", ".join(sorted(m.value for m in WalletVersion))
)
)
return cast(WalletVersion, version)
def __init__(
self,
+8 -17
View File
@@ -7,6 +7,14 @@ from tonutils.contracts.wallet import WalletV4R2, WalletV5R1
WALLET_CLASSES: dict[str, Any] = {"V4R2": WalletV4R2, "V5R1": WalletV5R1}
# Stars limits
STARS_PURCHASE_MIN: int = 50
STARS_PURCHASE_MAX: int = 10_000
STARS_GIVEAWAY_MIN: int = 500
STARS_GIVEAWAY_MAX: int = 1_000_000
STARS_WINNERS_MIN: int = 1
STARS_WINNERS_MAX: int = 5
MIN_TON_BALANCE: float = 0.33
USDT_TON_MASTER_ADDRESS: str = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"
MIN_USDT_BALANCE: float = 0.75
@@ -25,23 +33,6 @@ ADS_TOPUP_PAGE: str = f"{FRAGMENT_BASE_URL}/ads/topup"
NUMBERS_PAGE: str = f"{FRAGMENT_BASE_URL}/numbers"
GIFTS_PAGE: str = f"{FRAGMENT_BASE_URL}/gifts"
SUPPORTED_BROWSERS: frozenset[str] = frozenset(
{
"arc",
"brave",
"chrome",
"chromium",
"chromium_based",
"edge",
"firefox",
"firefox_based",
"librewolf",
"opera",
"opera_gx",
"safari",
"vivaldi",
}
)
DEVICE: str = json.dumps(
{
+4 -3
View File
@@ -4,9 +4,10 @@ import importlib
from datetime import datetime, timezone
from typing import Any
from pyfragment.core.constants import FRAGMENT_BASE_URL, FRAGMENT_DOMAIN, REQUIRED_COOKIE_KEYS, SUPPORTED_BROWSERS
from pyfragment.core.constants import FRAGMENT_BASE_URL, FRAGMENT_DOMAIN, REQUIRED_COOKIE_KEYS
from pyfragment.exceptions import CookieError
from pyfragment.models.cookies import CookieResult
from pyfragment.models.enums import SupportedBrowser
try:
import rookiepy
@@ -18,8 +19,8 @@ def get_cookies_from_browser(browser: str = "chrome") -> CookieResult:
global rookiepy
key = browser.lower()
if key not in SUPPORTED_BROWSERS:
supported = ", ".join(sorted(SUPPORTED_BROWSERS))
if key not in SupportedBrowser._value2member_map_:
supported = ", ".join(sorted(b.value for b in SupportedBrowser))
raise CookieError(CookieError.UNSUPPORTED_BROWSER.format(browser=browser, supported=supported))
try:
+8 -8
View File
@@ -3,9 +3,9 @@ from __future__ import annotations
import json
import logging
import random
from typing import TYPE_CHECKING, get_args
from typing import TYPE_CHECKING
from pyfragment.core.constants import DEVICE, PREMIUM_GIVEAWAY_PAGE, STARS_GIVEAWAY_PAGE
from pyfragment.core.constants import DEVICE, PREMIUM_GIVEAWAY_PAGE, STARS_GIVEAWAY_PAGE, STARS_GIVEAWAY_MIN, STARS_GIVEAWAY_MAX, STARS_WINNERS_MIN, STARS_WINNERS_MAX
from pyfragment.domains.payments import parse_required_payment_amount
from pyfragment.domains.tonapi.account import get_account_info
from pyfragment.domains.tonapi.transaction import process_transaction
@@ -34,15 +34,15 @@ async def giveaway_stars(
amount: int,
payment_method: PaymentMethod = "ton",
) -> StarsGiveawayResult:
if not isinstance(winners, int) or not (1 <= winners <= 5):
if not isinstance(winners, int) or not (STARS_WINNERS_MIN <= winners <= STARS_WINNERS_MAX):
raise ConfigurationError(ConfigurationError.INVALID_WINNERS_STARS)
if not isinstance(amount, int) or not (500 <= amount <= 1_000_000):
if not isinstance(amount, int) or not (STARS_GIVEAWAY_MIN <= amount <= STARS_GIVEAWAY_MAX):
raise ConfigurationError(ConfigurationError.INVALID_STARS_PER_WINNER)
if payment_method not in get_args(PaymentMethod):
if payment_method not in PaymentMethod._value2member_map_:
raise ConfigurationError(
ConfigurationError.INVALID_PAYMENT_METHOD.format(
method=payment_method,
supported=", ".join(sorted(get_args(PaymentMethod))),
supported=", ".join(sorted(m.value for m in PaymentMethod)),
)
)
@@ -128,11 +128,11 @@ async def giveaway_premium(
raise ConfigurationError(ConfigurationError.INVALID_WINNERS_PREMIUM)
if months not in (3, 6, 12):
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
if payment_method not in get_args(PaymentMethod):
if payment_method not in PaymentMethod._value2member_map_:
raise ConfigurationError(
ConfigurationError.INVALID_PAYMENT_METHOD.format(
method=payment_method,
supported=", ".join(sorted(get_args(PaymentMethod))),
supported=", ".join(sorted(PaymentMethod._value2member_map_)),
)
)
+7 -7
View File
@@ -3,9 +3,9 @@ from __future__ import annotations
import json
import logging
import time
from typing import TYPE_CHECKING, get_args
from typing import TYPE_CHECKING
from pyfragment.core.constants import DEVICE, PREMIUM_PAGE, STARS_PAGE
from pyfragment.core.constants import DEVICE, PREMIUM_PAGE, STARS_PAGE, STARS_PURCHASE_MIN, STARS_PURCHASE_MAX
from pyfragment.domains.payments import parse_required_payment_amount
from pyfragment.domains.tonapi.account import get_account_info
from pyfragment.domains.tonapi.transaction import process_transaction
@@ -34,13 +34,13 @@ async def purchase_stars(
show_sender: bool = True,
payment_method: PaymentMethod = "ton",
) -> StarsResult:
if not isinstance(amount, int) or not (50 <= amount <= 1_000_000):
if not isinstance(amount, int) or not (STARS_PURCHASE_MIN <= amount <= STARS_PURCHASE_MAX):
raise ConfigurationError(ConfigurationError.INVALID_STARS_AMOUNT)
if payment_method not in get_args(PaymentMethod):
if payment_method not in PaymentMethod._value2member_map_:
raise ConfigurationError(
ConfigurationError.INVALID_PAYMENT_METHOD.format(
method=payment_method,
supported=", ".join(sorted(get_args(PaymentMethod))),
supported=", ".join(sorted(PaymentMethod._value2member_map_)),
)
)
@@ -117,11 +117,11 @@ async def purchase_premium(
) -> PremiumResult:
if months not in (3, 6, 12):
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
if payment_method not in get_args(PaymentMethod):
if payment_method not in PaymentMethod._value2member_map_:
raise ConfigurationError(
ConfigurationError.INVALID_PAYMENT_METHOD.format(
method=payment_method,
supported=", ".join(sorted(get_args(PaymentMethod))),
supported=", ".join(sorted(PaymentMethod._value2member_map_)),
)
)
+2 -2
View File
@@ -19,7 +19,7 @@ class ConfigurationError(ClientError):
"Invalid Tonapi API key: expected at least 68 characters, got {length}. Get a key at https://tonconsole.com."
)
INVALID_MONTHS = "Invalid Premium duration: choose 3, 6, or 12 months."
INVALID_STARS_AMOUNT = "Invalid Stars amount: must be an integer between 50 and 1,000,000."
INVALID_STARS_AMOUNT = "Invalid Stars amount: must be an integer between 50 and 10,000."
INVALID_TON_AMOUNT = "Invalid TON amount: must be an integer between 1 and 1,000,000,000."
INVALID_USERNAME = (
"Invalid username '{username}'. "
@@ -27,7 +27,7 @@ class ConfigurationError(ClientError):
)
INVALID_WINNERS_STARS = "Invalid winners count: must be an integer between 1 and 5."
INVALID_WINNERS_PREMIUM = "Invalid winners count: must be an integer between 1 and 24,000."
INVALID_STARS_PER_WINNER = "Invalid Stars per winner: must be an integer between 500 and 1,000,000."
INVALID_STARS_PER_WINNER = "Invalid Stars per winner: must be an integer between 500 and 1,000,000 (max total: 1,000,000)."
INVALID_PAYMENT_METHOD = "Invalid payment method '{method}'. Supported values: {supported}."
+28 -4
View File
@@ -1,8 +1,32 @@
from __future__ import annotations
from typing import Literal
from enum import StrEnum
PaymentMethod = Literal["ton", "usdt_ton"]
WalletVersion = Literal["V4R2", "V5R1"]
__all__ = ["PaymentMethod", "WalletVersion"]
class PaymentMethod(StrEnum):
TON = "ton"
USDT_TON = "usdt_ton"
class WalletVersion(StrEnum):
V4R2 = "V4R2"
V5R1 = "V5R1"
class SupportedBrowser(StrEnum):
ARC = "arc"
BRAVE = "brave"
CHROME = "chrome"
CHROMIUM = "chromium"
CHROMIUM_BASED = "chromium_based"
EDGE = "edge"
FIREFOX = "firefox"
FIREFOX_BASED = "firefox_based"
LIBREWOLF = "librewolf"
OPERA = "opera"
OPERA_GX = "opera_gx"
SAFARI = "safari"
VIVALDI = "vivaldi"
__all__ = ["PaymentMethod", "SupportedBrowser", "WalletVersion"]