mirror of
https://github.com/bohd4nx/FragmentAPI.git
synced 2026-07-25 06:14:29 +00:00
feat: enhance FragmentClient to support custom headers; update limits for TON topup and stars purchases
This commit is contained in:
@@ -4,6 +4,7 @@ import json
|
||||
from typing import Any, cast
|
||||
|
||||
from pyfragment.core.constants import (
|
||||
BASE_HEADERS,
|
||||
DEFAULT_TIMEOUT,
|
||||
FRAGMENT_BASE_URL,
|
||||
MNEMONIC_WORD_COUNTS_VALID,
|
||||
@@ -40,6 +41,7 @@ class FragmentClient:
|
||||
cookies: Fragment session cookies as a dict or JSON string.
|
||||
wallet_version: Wallet contract version — ``"V4R2"`` or ``"V5R1"`` (default).
|
||||
timeout: HTTP request timeout in seconds. Defaults to ``30.0``.
|
||||
headers: Custom HTTP request headers. If omitted, :data:`BASE_HEADERS` is used.
|
||||
|
||||
Raises:
|
||||
ConfigurationError: If ``seed``, ``api_key``, or ``wallet_version`` are missing or invalid.
|
||||
@@ -104,6 +106,7 @@ class FragmentClient:
|
||||
cookies: dict[str, Any] | str,
|
||||
wallet_version: str = "V5R1",
|
||||
timeout: float = DEFAULT_TIMEOUT,
|
||||
headers: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
self._validate_required(seed, api_key)
|
||||
parsed_cookies = self._parse_cookies(cookies)
|
||||
@@ -115,6 +118,7 @@ class FragmentClient:
|
||||
self.cookies: dict[str, Any] = parsed_cookies
|
||||
self.wallet_version: WalletVersion = version
|
||||
self.timeout: float = timeout
|
||||
self.headers: dict[str, str] = headers if headers is not None else BASE_HEADERS
|
||||
self.marketplace = MarketplaceService(self)
|
||||
self.purchases = PurchasesService(self)
|
||||
self.giveaways = GiveawaysService(self)
|
||||
@@ -391,4 +395,4 @@ class FragmentClient:
|
||||
page_url="https://fragment.com/premium/gift",
|
||||
)
|
||||
"""
|
||||
return await raw_api_call(self.cookies, self.timeout, method, data, page_url)
|
||||
return await raw_api_call(self.cookies, self.timeout, method, data, page_url, self.headers)
|
||||
|
||||
@@ -14,6 +14,8 @@ from pyfragment.core.constants.limits import (
|
||||
STARS_PURCHASE_MIN,
|
||||
STARS_WINNERS_MAX,
|
||||
STARS_WINNERS_MIN,
|
||||
TON_TOPUP_MAX,
|
||||
TON_TOPUP_MIN,
|
||||
TONAPI_KEY_MIN_LENGTH,
|
||||
)
|
||||
from pyfragment.core.constants.ton import DEVICE_INFO, USDT_TON_MASTER_ADDRESS
|
||||
@@ -56,5 +58,7 @@ __all__ = [
|
||||
"STARS_WINNERS_MAX",
|
||||
"STARS_WINNERS_MIN",
|
||||
"TONAPI_KEY_MIN_LENGTH",
|
||||
"TON_TOPUP_MAX",
|
||||
"TON_TOPUP_MIN",
|
||||
"USDT_TON_MASTER_ADDRESS",
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
# Stars: direct purchase
|
||||
STARS_PURCHASE_MIN: int = 50
|
||||
STARS_PURCHASE_MAX: int = 10_000
|
||||
STARS_PURCHASE_MAX: int = 10_000_000
|
||||
|
||||
# Stars: giveaway per winner
|
||||
STARS_GIVEAWAY_MIN: int = 500
|
||||
@@ -10,12 +10,20 @@ STARS_GIVEAWAY_MAX: int = 1_000_000
|
||||
|
||||
# Stars giveaway winners count
|
||||
STARS_WINNERS_MIN: int = 1
|
||||
STARS_WINNERS_MAX: int = 5
|
||||
STARS_WINNERS_MAX: int = 15
|
||||
|
||||
# Premium giveaway winners count
|
||||
PREMIUM_WINNERS_MIN: int = 1
|
||||
PREMIUM_WINNERS_MAX: int = 24_000
|
||||
|
||||
# TON topup / Ads recharge amount
|
||||
TON_TOPUP_MIN: int = 1
|
||||
TON_TOPUP_MAX: int = 1_000_000_000
|
||||
|
||||
# Wallet minimum balances
|
||||
MIN_TON_BALANCE: float = 0.33
|
||||
MIN_USDT_BALANCE: float = 0.75
|
||||
|
||||
# Premium subscription durations (months)
|
||||
PREMIUM_MONTHS_VALID: frozenset[int] = frozenset({3, 6, 12})
|
||||
|
||||
@@ -24,7 +32,3 @@ 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
|
||||
|
||||
@@ -4,7 +4,7 @@ import json
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from pyfragment.core.constants import ADS_TOPUP_PAGE, DEVICE_INFO
|
||||
from pyfragment.core.constants import ADS_TOPUP_PAGE, DEVICE_INFO, TON_TOPUP_MAX, TON_TOPUP_MIN
|
||||
from pyfragment.domains.tonapi.account import get_account_info
|
||||
from pyfragment.domains.tonapi.transaction import process_transaction
|
||||
from pyfragment.exceptions import ConfigurationError, FragmentAPIError, FragmentError, UnexpectedError, VerificationError
|
||||
@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def recharge_ads(client: FragmentClient, account: str, amount: int) -> AdsRechargeResult:
|
||||
if not isinstance(amount, int) or not (1 <= amount <= 1_000_000_000):
|
||||
if not isinstance(amount, int) or not (TON_TOPUP_MIN <= amount <= TON_TOPUP_MAX):
|
||||
raise ConfigurationError(ConfigurationError.INVALID_TON_AMOUNT)
|
||||
|
||||
try:
|
||||
|
||||
@@ -4,7 +4,7 @@ import json
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from pyfragment.core.constants import ADS_TOPUP_PAGE, DEVICE_INFO
|
||||
from pyfragment.core.constants import ADS_TOPUP_PAGE, DEVICE_INFO, TON_TOPUP_MAX, TON_TOPUP_MIN
|
||||
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
|
||||
@@ -26,7 +26,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def topup_ton(client: FragmentClient, username: str, amount: int, show_sender: bool = True) -> AdsTopupResult:
|
||||
if not isinstance(amount, int) or not (1 <= amount <= 1_000_000_000):
|
||||
if not isinstance(amount, int) or not (TON_TOPUP_MIN <= amount <= TON_TOPUP_MAX):
|
||||
raise ConfigurationError(ConfigurationError.INVALID_TON_AMOUNT)
|
||||
|
||||
try:
|
||||
|
||||
@@ -20,14 +20,16 @@ async def raw_api_call(
|
||||
method: str,
|
||||
data: dict[str, Any] | None,
|
||||
page_url: str,
|
||||
headers: dict[str, str] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
base = headers if headers is not None else BASE_HEADERS
|
||||
payload = {"method": method, **(data or {})}
|
||||
headers = {**BASE_HEADERS, "referer": page_url, "x-aj-referer": page_url}
|
||||
call_headers = {**base, "referer": page_url, "x-aj-referer": page_url}
|
||||
logger.debug("Starting Fragment API call '%s' on %s", method, page_url)
|
||||
try:
|
||||
async with httpx.AsyncClient(cookies=cookies, timeout=timeout) as session:
|
||||
fragment_hash = await get_fragment_hash(cookies, headers, page_url, timeout)
|
||||
response = await fragment_request(session, fragment_hash, headers, payload)
|
||||
fragment_hash = await get_fragment_hash(cookies, call_headers, page_url, timeout)
|
||||
response = await fragment_request(session, fragment_hash, call_headers, payload)
|
||||
logger.debug("Completed Fragment API call '%s' with response keys: %s", method, sorted(response.keys()))
|
||||
return response
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user