mirror of
https://github.com/bohd4nx/FragmentAPI.git
synced 2026-07-25 06:14:29 +00:00
feat: reorganize constants into separate modules; update validation logic for mnemonic and API key lengths
This commit is contained in:
@@ -3,7 +3,13 @@ from __future__ import annotations
|
|||||||
import json
|
import json
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from pyfragment.core.constants import DEFAULT_TIMEOUT, FRAGMENT_BASE_URL, REQUIRED_COOKIE_KEYS
|
from pyfragment.core.constants import (
|
||||||
|
DEFAULT_TIMEOUT,
|
||||||
|
FRAGMENT_BASE_URL,
|
||||||
|
MNEMONIC_WORD_COUNTS_VALID,
|
||||||
|
REQUIRED_COOKIE_KEYS,
|
||||||
|
TONAPI_KEY_MIN_LENGTH,
|
||||||
|
)
|
||||||
from pyfragment.domains.ads.service import AdsService
|
from pyfragment.domains.ads.service import AdsService
|
||||||
from pyfragment.domains.anonymous_numbers.service import AnonymousNumbersService
|
from pyfragment.domains.anonymous_numbers.service import AnonymousNumbersService
|
||||||
from pyfragment.domains.base import raw_api_call
|
from pyfragment.domains.base import raw_api_call
|
||||||
@@ -67,10 +73,10 @@ class FragmentClient:
|
|||||||
raise ConfigurationError(ConfigurationError.MISSING_VARS.format(keys=", ".join(missing)))
|
raise ConfigurationError(ConfigurationError.MISSING_VARS.format(keys=", ".join(missing)))
|
||||||
|
|
||||||
word_count = len(seed.split())
|
word_count = len(seed.split())
|
||||||
if word_count not in (12, 18, 24):
|
if word_count not in MNEMONIC_WORD_COUNTS_VALID:
|
||||||
raise ConfigurationError(ConfigurationError.INVALID_MNEMONIC.format(count=word_count))
|
raise ConfigurationError(ConfigurationError.INVALID_MNEMONIC.format(count=word_count))
|
||||||
|
|
||||||
if len(api_key.strip()) < 68:
|
if len(api_key.strip()) < TONAPI_KEY_MIN_LENGTH:
|
||||||
raise ConfigurationError(ConfigurationError.INVALID_API_KEY.format(length=len(api_key.strip())))
|
raise ConfigurationError(ConfigurationError.INVALID_API_KEY.format(length=len(api_key.strip())))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
DEFAULT_TIMEOUT: float = 30.0
|
|
||||||
|
|
||||||
REQUIRED_COOKIE_KEYS: tuple[str, ...] = ("stel_ssid", "stel_dt", "stel_token", "stel_ton_token")
|
|
||||||
|
|
||||||
FRAGMENT_DOMAIN: str = "fragment.com"
|
|
||||||
FRAGMENT_BASE_URL: str = f"https://{FRAGMENT_DOMAIN}"
|
|
||||||
STARS_PAGE: str = f"{FRAGMENT_BASE_URL}/stars/buy"
|
|
||||||
STARS_GIVEAWAY_PAGE: str = f"{FRAGMENT_BASE_URL}/stars/giveaway"
|
|
||||||
PREMIUM_PAGE: str = f"{FRAGMENT_BASE_URL}/premium/gift"
|
|
||||||
PREMIUM_GIVEAWAY_PAGE: str = f"{FRAGMENT_BASE_URL}/premium/giveaway"
|
|
||||||
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"
|
|
||||||
|
|
||||||
|
|
||||||
DEVICE: str = json.dumps(
|
|
||||||
{
|
|
||||||
"platform": "iphone",
|
|
||||||
"appName": "Tonkeeper",
|
|
||||||
"appVersion": "26.04.0",
|
|
||||||
"maxProtocolVersion": 2,
|
|
||||||
"features": [
|
|
||||||
"SendTransaction",
|
|
||||||
{"name": "SendTransaction", "maxMessages": 255},
|
|
||||||
{"name": "SignData", "types": ["text", "binary", "cell"]},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
BASE_HEADERS: dict[str, str] = {
|
|
||||||
"accept": "application/json, text/javascript, */*; q=0.01",
|
|
||||||
"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",
|
|
||||||
"origin": FRAGMENT_BASE_URL,
|
|
||||||
"priority": "u=1, i",
|
|
||||||
"sec-ch-ua": '"Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
|
|
||||||
"sec-ch-ua-mobile": "?1",
|
|
||||||
"sec-ch-ua-platform": '"Android"',
|
|
||||||
"sec-fetch-dest": "empty",
|
|
||||||
"sec-fetch-mode": "cors",
|
|
||||||
"sec-fetch-site": "same-origin",
|
|
||||||
"user-agent": (
|
|
||||||
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) "
|
|
||||||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Mobile Safari/537.36"
|
|
||||||
),
|
|
||||||
"x-requested-with": "XMLHttpRequest",
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pyfragment.core.constants.headers import BASE_HEADERS, DEFAULT_TIMEOUT, REQUIRED_COOKIE_KEYS
|
||||||
|
from pyfragment.core.constants.limits import (
|
||||||
|
MIN_TON_BALANCE,
|
||||||
|
MIN_USDT_BALANCE,
|
||||||
|
MNEMONIC_WORD_COUNTS_VALID,
|
||||||
|
PREMIUM_MONTHS_VALID,
|
||||||
|
PREMIUM_WINNERS_MAX,
|
||||||
|
PREMIUM_WINNERS_MIN,
|
||||||
|
STARS_GIVEAWAY_MAX,
|
||||||
|
STARS_GIVEAWAY_MIN,
|
||||||
|
STARS_PURCHASE_MAX,
|
||||||
|
STARS_PURCHASE_MIN,
|
||||||
|
STARS_WINNERS_MAX,
|
||||||
|
STARS_WINNERS_MIN,
|
||||||
|
TONAPI_KEY_MIN_LENGTH,
|
||||||
|
)
|
||||||
|
from pyfragment.core.constants.ton import DEVICE_INFO, USDT_TON_MASTER_ADDRESS
|
||||||
|
from pyfragment.core.constants.urls import (
|
||||||
|
ADS_TOPUP_PAGE,
|
||||||
|
FRAGMENT_BASE_URL,
|
||||||
|
FRAGMENT_DOMAIN,
|
||||||
|
GIFTS_PAGE,
|
||||||
|
NUMBERS_PAGE,
|
||||||
|
PREMIUM_GIVEAWAY_PAGE,
|
||||||
|
PREMIUM_PAGE,
|
||||||
|
STARS_GIVEAWAY_PAGE,
|
||||||
|
STARS_PAGE,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ADS_TOPUP_PAGE",
|
||||||
|
"BASE_HEADERS",
|
||||||
|
"DEFAULT_TIMEOUT",
|
||||||
|
"DEVICE_INFO",
|
||||||
|
"FRAGMENT_BASE_URL",
|
||||||
|
"FRAGMENT_DOMAIN",
|
||||||
|
"GIFTS_PAGE",
|
||||||
|
"MIN_TON_BALANCE",
|
||||||
|
"MIN_USDT_BALANCE",
|
||||||
|
"MNEMONIC_WORD_COUNTS_VALID",
|
||||||
|
"NUMBERS_PAGE",
|
||||||
|
"PREMIUM_GIVEAWAY_PAGE",
|
||||||
|
"PREMIUM_MONTHS_VALID",
|
||||||
|
"PREMIUM_PAGE",
|
||||||
|
"PREMIUM_WINNERS_MAX",
|
||||||
|
"PREMIUM_WINNERS_MIN",
|
||||||
|
"REQUIRED_COOKIE_KEYS",
|
||||||
|
"STARS_GIVEAWAY_MAX",
|
||||||
|
"STARS_GIVEAWAY_MIN",
|
||||||
|
"STARS_GIVEAWAY_PAGE",
|
||||||
|
"STARS_PAGE",
|
||||||
|
"STARS_PURCHASE_MAX",
|
||||||
|
"STARS_PURCHASE_MIN",
|
||||||
|
"STARS_WINNERS_MAX",
|
||||||
|
"STARS_WINNERS_MIN",
|
||||||
|
"TONAPI_KEY_MIN_LENGTH",
|
||||||
|
"USDT_TON_MASTER_ADDRESS",
|
||||||
|
]
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pyfragment.core.constants.urls import FRAGMENT_BASE_URL
|
||||||
|
|
||||||
|
DEFAULT_TIMEOUT: float = 30.0
|
||||||
|
|
||||||
|
REQUIRED_COOKIE_KEYS: tuple[str, ...] = ("stel_ssid", "stel_dt", "stel_token", "stel_ton_token")
|
||||||
|
|
||||||
|
BASE_HEADERS: dict[str, str] = {
|
||||||
|
"accept": "application/json, text/javascript, */*; q=0.01",
|
||||||
|
"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",
|
||||||
|
"origin": FRAGMENT_BASE_URL,
|
||||||
|
"priority": "u=1, i",
|
||||||
|
"sec-ch-ua": '"Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
|
||||||
|
"sec-ch-ua-mobile": "?1",
|
||||||
|
"sec-ch-ua-platform": '"Android"',
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"user-agent": (
|
||||||
|
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) "
|
||||||
|
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Mobile Safari/537.36"
|
||||||
|
),
|
||||||
|
"x-requested-with": "XMLHttpRequest",
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
# Stars: direct purchase
|
||||||
|
STARS_PURCHASE_MIN: int = 50
|
||||||
|
STARS_PURCHASE_MAX: int = 10_000
|
||||||
|
|
||||||
|
# Stars: giveaway per winner
|
||||||
|
STARS_GIVEAWAY_MIN: int = 500
|
||||||
|
STARS_GIVEAWAY_MAX: int = 1_000_000
|
||||||
|
|
||||||
|
# Stars giveaway winners count
|
||||||
|
STARS_WINNERS_MIN: int = 1
|
||||||
|
STARS_WINNERS_MAX: int = 5
|
||||||
|
|
||||||
|
# Premium giveaway winners count
|
||||||
|
PREMIUM_WINNERS_MIN: int = 1
|
||||||
|
PREMIUM_WINNERS_MAX: int = 24_000
|
||||||
|
|
||||||
|
# Premium subscription durations (months)
|
||||||
|
PREMIUM_MONTHS_VALID: frozenset[int] = frozenset({3, 6, 12})
|
||||||
|
|
||||||
|
# Mnemonic phrase valid word counts
|
||||||
|
MNEMONIC_WORD_COUNTS_VALID: frozenset[int] = frozenset({12, 24})
|
||||||
|
|
||||||
|
# Tonapi API key minimum length
|
||||||
|
TONAPI_KEY_MIN_LENGTH: int = 68
|
||||||
|
|
||||||
|
# Wallet minimum balances
|
||||||
|
MIN_TON_BALANCE: float = 0.33
|
||||||
|
MIN_USDT_BALANCE: float = 0.75
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
USDT_TON_MASTER_ADDRESS: str = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"
|
||||||
|
|
||||||
|
DEVICE_INFO: dict[str, Any] = {
|
||||||
|
"platform": "iphone",
|
||||||
|
"appName": "Tonkeeper",
|
||||||
|
"appVersion": "26.04.0",
|
||||||
|
"maxProtocolVersion": 2,
|
||||||
|
"features": [
|
||||||
|
"SendTransaction",
|
||||||
|
{"name": "SendTransaction", "maxMessages": 255},
|
||||||
|
{"name": "SignData", "types": ["text", "binary", "cell"]},
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
FRAGMENT_DOMAIN: str = "fragment.com"
|
||||||
|
FRAGMENT_BASE_URL: str = f"https://{FRAGMENT_DOMAIN}"
|
||||||
|
|
||||||
|
STARS_PAGE: str = f"{FRAGMENT_BASE_URL}/stars/buy"
|
||||||
|
STARS_GIVEAWAY_PAGE: str = f"{FRAGMENT_BASE_URL}/stars/giveaway"
|
||||||
|
PREMIUM_PAGE: str = f"{FRAGMENT_BASE_URL}/premium/gift"
|
||||||
|
PREMIUM_GIVEAWAY_PAGE: str = f"{FRAGMENT_BASE_URL}/premium/giveaway"
|
||||||
|
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"
|
||||||
@@ -5,7 +5,18 @@ import logging
|
|||||||
import random
|
import random
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
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.core.constants import (
|
||||||
|
DEVICE,
|
||||||
|
PREMIUM_GIVEAWAY_PAGE,
|
||||||
|
PREMIUM_MONTHS_VALID,
|
||||||
|
PREMIUM_WINNERS_MAX,
|
||||||
|
PREMIUM_WINNERS_MIN,
|
||||||
|
STARS_GIVEAWAY_MAX,
|
||||||
|
STARS_GIVEAWAY_MIN,
|
||||||
|
STARS_GIVEAWAY_PAGE,
|
||||||
|
STARS_WINNERS_MAX,
|
||||||
|
STARS_WINNERS_MIN,
|
||||||
|
)
|
||||||
from pyfragment.domains.payments import parse_required_payment_amount
|
from pyfragment.domains.payments import parse_required_payment_amount
|
||||||
from pyfragment.domains.tonapi.account import get_account_info
|
from pyfragment.domains.tonapi.account import get_account_info
|
||||||
from pyfragment.domains.tonapi.transaction import process_transaction
|
from pyfragment.domains.tonapi.transaction import process_transaction
|
||||||
@@ -124,9 +135,9 @@ async def giveaway_premium(
|
|||||||
months: int = 3,
|
months: int = 3,
|
||||||
payment_method: PaymentMethod = "ton",
|
payment_method: PaymentMethod = "ton",
|
||||||
) -> PremiumGiveawayResult:
|
) -> PremiumGiveawayResult:
|
||||||
if not isinstance(winners, int) or not (1 <= winners <= 24_000):
|
if not isinstance(winners, int) or not (PREMIUM_WINNERS_MIN <= winners <= PREMIUM_WINNERS_MAX):
|
||||||
raise ConfigurationError(ConfigurationError.INVALID_WINNERS_PREMIUM)
|
raise ConfigurationError(ConfigurationError.INVALID_WINNERS_PREMIUM)
|
||||||
if months not in (3, 6, 12):
|
if months not in PREMIUM_MONTHS_VALID:
|
||||||
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
|
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
|
||||||
if payment_method not in PaymentMethod._value2member_map_:
|
if payment_method not in PaymentMethod._value2member_map_:
|
||||||
raise ConfigurationError(
|
raise ConfigurationError(
|
||||||
|
|||||||
@@ -5,7 +5,14 @@ import logging
|
|||||||
import time
|
import time
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from pyfragment.core.constants import DEVICE, PREMIUM_PAGE, STARS_PAGE, STARS_PURCHASE_MIN, STARS_PURCHASE_MAX
|
from pyfragment.core.constants import (
|
||||||
|
DEVICE,
|
||||||
|
PREMIUM_MONTHS_VALID,
|
||||||
|
PREMIUM_PAGE,
|
||||||
|
STARS_PAGE,
|
||||||
|
STARS_PURCHASE_MAX,
|
||||||
|
STARS_PURCHASE_MIN,
|
||||||
|
)
|
||||||
from pyfragment.domains.payments import parse_required_payment_amount
|
from pyfragment.domains.payments import parse_required_payment_amount
|
||||||
from pyfragment.domains.tonapi.account import get_account_info
|
from pyfragment.domains.tonapi.account import get_account_info
|
||||||
from pyfragment.domains.tonapi.transaction import process_transaction
|
from pyfragment.domains.tonapi.transaction import process_transaction
|
||||||
@@ -115,7 +122,7 @@ async def purchase_premium(
|
|||||||
show_sender: bool = True,
|
show_sender: bool = True,
|
||||||
payment_method: PaymentMethod = "ton",
|
payment_method: PaymentMethod = "ton",
|
||||||
) -> PremiumResult:
|
) -> PremiumResult:
|
||||||
if months not in (3, 6, 12):
|
if months not in PREMIUM_MONTHS_VALID:
|
||||||
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
|
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
|
||||||
if payment_method not in PaymentMethod._value2member_map_:
|
if payment_method not in PaymentMethod._value2member_map_:
|
||||||
raise ConfigurationError(
|
raise ConfigurationError(
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ from tonutils.clients import TonapiClient
|
|||||||
from tonutils.contracts.jetton import get_wallet_address_get_method, get_wallet_data_get_method
|
from tonutils.contracts.jetton import get_wallet_address_get_method, get_wallet_data_get_method
|
||||||
from tonutils.exceptions import ProviderResponseError
|
from tonutils.exceptions import ProviderResponseError
|
||||||
|
|
||||||
from pyfragment.core.constants import MIN_TON_BALANCE, MIN_USDT_BALANCE, USDT_TON_MASTER_ADDRESS, WALLET_CLASSES
|
from pyfragment.core.constants import MIN_TON_BALANCE, MIN_USDT_BALANCE, USDT_TON_MASTER_ADDRESS
|
||||||
from pyfragment.exceptions import WalletError
|
from pyfragment.exceptions import WalletError
|
||||||
|
from pyfragment.models.enums import WALLET_CLASSES
|
||||||
from pyfragment.models.wallet import WalletInfo
|
from pyfragment.models.wallet import WalletInfo
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|||||||
@@ -11,10 +11,9 @@ from ton_core import Cell, NetworkGlobalID
|
|||||||
from tonutils.clients import TonapiClient
|
from tonutils.clients import TonapiClient
|
||||||
from tonutils.exceptions import ProviderResponseError
|
from tonutils.exceptions import ProviderResponseError
|
||||||
|
|
||||||
from pyfragment.core.constants import WALLET_CLASSES
|
|
||||||
from pyfragment.domains.tonapi.account import check_ton_payment_balance, check_usdt_payment_balance
|
from pyfragment.domains.tonapi.account import check_ton_payment_balance, check_usdt_payment_balance
|
||||||
from pyfragment.exceptions import ParseError, TransactionError, WalletError
|
from pyfragment.exceptions import ParseError, TransactionError, WalletError
|
||||||
from pyfragment.models.enums import PaymentMethod
|
from pyfragment.models.enums import WALLET_CLASSES, PaymentMethod
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from pyfragment.client import FragmentClient
|
from pyfragment.client import FragmentClient
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pyfragment.core.constants.limits import (
|
||||||
|
MNEMONIC_WORD_COUNTS_VALID,
|
||||||
|
PREMIUM_MONTHS_VALID,
|
||||||
|
PREMIUM_WINNERS_MAX,
|
||||||
|
PREMIUM_WINNERS_MIN,
|
||||||
|
STARS_GIVEAWAY_MAX,
|
||||||
|
STARS_GIVEAWAY_MIN,
|
||||||
|
STARS_PURCHASE_MAX,
|
||||||
|
STARS_PURCHASE_MIN,
|
||||||
|
STARS_WINNERS_MAX,
|
||||||
|
STARS_WINNERS_MIN,
|
||||||
|
TONAPI_KEY_MIN_LENGTH,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FragmentError(Exception):
|
class FragmentError(Exception):
|
||||||
"""Base exception for all pyfragment errors."""
|
"""Base exception for all pyfragment errors."""
|
||||||
@@ -14,20 +28,29 @@ class ConfigurationError(ClientError):
|
|||||||
|
|
||||||
MISSING_VARS = "Missing required parameter(s): {keys}."
|
MISSING_VARS = "Missing required parameter(s): {keys}."
|
||||||
UNSUPPORTED_VERSION = "Unsupported wallet version '{version}'. Supported values: {supported}."
|
UNSUPPORTED_VERSION = "Unsupported wallet version '{version}'. Supported values: {supported}."
|
||||||
INVALID_MNEMONIC = "Invalid mnemonic phrase: expected 12, 18, or 24 words, got {count}."
|
INVALID_MNEMONIC = f"Invalid mnemonic phrase: expected {', '.join(str(n) for n in sorted(MNEMONIC_WORD_COUNTS_VALID))} words, got {{count}}."
|
||||||
INVALID_API_KEY = (
|
INVALID_API_KEY = (
|
||||||
"Invalid Tonapi API key: expected at least 68 characters, got {length}. Get a key at https://tonconsole.com."
|
f"Invalid Tonapi API key: expected at least {TONAPI_KEY_MIN_LENGTH} characters, got {{length}}. "
|
||||||
|
"Get a key at https://tonconsole.com."
|
||||||
|
)
|
||||||
|
INVALID_MONTHS = f"Invalid Premium duration: choose {', '.join(str(m) for m in sorted(PREMIUM_MONTHS_VALID))} months."
|
||||||
|
INVALID_STARS_AMOUNT = (
|
||||||
|
f"Invalid Stars amount: must be an integer between {STARS_PURCHASE_MIN:,} and {STARS_PURCHASE_MAX:,}."
|
||||||
)
|
)
|
||||||
INVALID_MONTHS = "Invalid Premium duration: choose 3, 6, or 12 months."
|
|
||||||
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_TON_AMOUNT = "Invalid TON amount: must be an integer between 1 and 1,000,000,000."
|
||||||
INVALID_USERNAME = (
|
INVALID_USERNAME = (
|
||||||
"Invalid username '{username}'. "
|
"Invalid username '{username}'. "
|
||||||
"Must be 5-32 characters and contain only letters (A-Z, a-z), digits (0-9), or underscores (_)."
|
"Must be 5-32 characters and contain only letters (A-Z, a-z), digits (0-9), or underscores (_)."
|
||||||
)
|
)
|
||||||
INVALID_WINNERS_STARS = "Invalid winners count: must be an integer between 1 and 5."
|
INVALID_WINNERS_STARS = (
|
||||||
INVALID_WINNERS_PREMIUM = "Invalid winners count: must be an integer between 1 and 24,000."
|
f"Invalid winners count: must be an integer between {STARS_WINNERS_MIN:,} and {STARS_WINNERS_MAX:,}."
|
||||||
INVALID_STARS_PER_WINNER = "Invalid Stars per winner: must be an integer between 500 and 1,000,000 (max total: 1,000,000)."
|
)
|
||||||
|
INVALID_WINNERS_PREMIUM = (
|
||||||
|
f"Invalid winners count: must be an integer between {PREMIUM_WINNERS_MIN:,} and {PREMIUM_WINNERS_MAX:,}."
|
||||||
|
)
|
||||||
|
INVALID_STARS_PER_WINNER = (
|
||||||
|
f"Invalid Stars per winner: must be an integer between {STARS_GIVEAWAY_MIN:,} and {STARS_GIVEAWAY_MAX:,}."
|
||||||
|
)
|
||||||
INVALID_PAYMENT_METHOD = "Invalid payment method '{method}'. Supported values: {supported}."
|
INVALID_PAYMENT_METHOD = "Invalid payment method '{method}'. Supported values: {supported}."
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from tonutils.contracts.wallet import WalletV4R2, WalletV5R1
|
||||||
|
|
||||||
|
|
||||||
class PaymentMethod(StrEnum):
|
class PaymentMethod(StrEnum):
|
||||||
@@ -13,6 +16,12 @@ class WalletVersion(StrEnum):
|
|||||||
V5R1 = "V5R1"
|
V5R1 = "V5R1"
|
||||||
|
|
||||||
|
|
||||||
|
WALLET_CLASSES: dict[WalletVersion, Any] = {
|
||||||
|
WalletVersion.V4R2: WalletV4R2,
|
||||||
|
WalletVersion.V5R1: WalletV5R1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SupportedBrowser(StrEnum):
|
class SupportedBrowser(StrEnum):
|
||||||
ARC = "arc"
|
ARC = "arc"
|
||||||
BRAVE = "brave"
|
BRAVE = "brave"
|
||||||
@@ -29,4 +38,4 @@ class SupportedBrowser(StrEnum):
|
|||||||
VIVALDI = "vivaldi"
|
VIVALDI = "vivaldi"
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["PaymentMethod", "SupportedBrowser", "WalletVersion"]
|
__all__ = ["PaymentMethod", "SupportedBrowser", "WALLET_CLASSES", "WalletVersion"]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import json
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pyfragment import ConfigurationError, CookieError, FragmentClient
|
from pyfragment import ConfigurationError, CookieError, FragmentClient
|
||||||
|
from pyfragment.core.constants.limits import MNEMONIC_WORD_COUNTS_VALID, TONAPI_KEY_MIN_LENGTH
|
||||||
from tests.shared import VALID_API_KEY, VALID_COOKIES, VALID_SEED
|
from tests.shared import VALID_API_KEY, VALID_COOKIES, VALID_SEED
|
||||||
|
|
||||||
# Client init tests
|
# Client init tests
|
||||||
@@ -55,7 +56,7 @@ def test_invalid_mnemonic_length_raises() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_valid_mnemonic_lengths() -> None:
|
def test_valid_mnemonic_lengths() -> None:
|
||||||
for length in (12, 18, 24):
|
for length in sorted(MNEMONIC_WORD_COUNTS_VALID):
|
||||||
seed = " ".join(["abandon"] * (length - 1) + ["about"])
|
seed = " ".join(["abandon"] * (length - 1) + ["about"])
|
||||||
client = FragmentClient(seed=seed, api_key=VALID_API_KEY, cookies=VALID_COOKIES)
|
client = FragmentClient(seed=seed, api_key=VALID_API_KEY, cookies=VALID_COOKIES)
|
||||||
assert len(client.seed.split()) == length
|
assert len(client.seed.split()) == length
|
||||||
@@ -71,7 +72,7 @@ def test_missing_api_key_raises() -> None:
|
|||||||
|
|
||||||
def test_short_api_key_raises() -> None:
|
def test_short_api_key_raises() -> None:
|
||||||
with pytest.raises(ConfigurationError):
|
with pytest.raises(ConfigurationError):
|
||||||
FragmentClient(seed=VALID_SEED, api_key="A" * 42, cookies=VALID_COOKIES)
|
FragmentClient(seed=VALID_SEED, api_key="A" * (TONAPI_KEY_MIN_LENGTH - 1), cookies=VALID_COOKIES)
|
||||||
|
|
||||||
|
|
||||||
# Cookie validation tests
|
# Cookie validation tests
|
||||||
|
|||||||
Reference in New Issue
Block a user