mirror of
https://github.com/bohd4nx/FragmentAPI.git
synced 2026-07-25 06:14:29 +00:00
4e03d2e2f6
- Security & validation: tighten hash regex, add HTTP timeouts to all requests, pass client.timeout through get_fragment_hash and AsyncClient - Constants: move all constants to types/constants.py; remove re-exports from types/__init__.py; add DEFAULT_TIMEOUT, REQUIRED_COOKIE_KEYS - FragmentClient: add timeout param (default 30 s); async-context-manager support; remove WALLET_CLASSES from public API - Exceptions: remove dead INVALID_USERNAME constant (Fragment validates server-side); keep full hierarchy intact - Tests: add 006_test_methods_mock.py (6 mock tests for all 3 methods); DRY-refactor 004_test_balance.py (_patch_wallet context manager); clean up 005_test_methods.py (remove fragile network test, rename tests) - Examples: switch all 4 examples to async-with; align error messages; replace %-format with f-strings - README: rewrite usage section with single comprehensive async-with example covering all 3 methods and full exception hierarchy - CI: add mypy step to lint job; add pytest-mock and mypy to dev deps; set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 on all jobs; fix COOKIES_JSON to job-level env var
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
import json
|
|
from typing import Literal, get_args
|
|
|
|
from tonutils.contracts.wallet import WalletV4R2, WalletV5R1
|
|
|
|
# Single source of truth for supported wallet versions
|
|
WalletVersion = Literal["V4R2", "V5R1"]
|
|
SUPPORTED_WALLET_VERSIONS: frozenset[str] = frozenset(get_args(WalletVersion))
|
|
|
|
# Wallet class map — used to resolve the correct contract from WALLET_VERSION
|
|
WALLET_CLASSES: dict[str, type] = {"V4R2": WalletV4R2, "V5R1": WalletV5R1}
|
|
|
|
# Minimum wallet balance required to cover TON network gas fees.
|
|
MIN_TON_BALANCE: float = 0.056
|
|
|
|
# Default HTTP request timeout in seconds.
|
|
DEFAULT_TIMEOUT: float = 30.0
|
|
|
|
# Required Fragment session cookie keys
|
|
REQUIRED_COOKIE_KEYS: tuple[str, ...] = ("stel_ssid", "stel_dt", "stel_token", "stel_ton_token")
|
|
|
|
# Fragment page URLs
|
|
STARS_PAGE: str = "https://fragment.com/stars/buy"
|
|
PREMIUM_PAGE: str = "https://fragment.com/premium/gift"
|
|
TON_PAGE: str = "https://fragment.com/ads/topup"
|
|
|
|
# Tonkeeper device fingerprint — serialized once, reused in every tx_data payload.
|
|
DEVICE: str = json.dumps(
|
|
{
|
|
"platform": "iphone",
|
|
"appName": "Tonkeeper",
|
|
"appVersion": "5.5.2",
|
|
"maxProtocolVersion": 2,
|
|
"features": [
|
|
"SendTransaction",
|
|
{"name": "SendTransaction", "maxMessages": 255},
|
|
{"name": "SignData", "types": ["text", "binary", "cell"]},
|
|
],
|
|
}
|
|
)
|
|
|
|
# Base HTTP headers — shared across all Fragment API requests.
|
|
# Each method merges these with its own "referer" and "x-aj-referer".
|
|
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": "https://fragment.com",
|
|
"priority": "u=1, i",
|
|
"sec-fetch-dest": "empty",
|
|
"sec-fetch-mode": "cors",
|
|
"sec-fetch-site": "same-origin",
|
|
"user-agent": (
|
|
"Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) "
|
|
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1"
|
|
),
|
|
"x-requested-with": "XMLHttpRequest",
|
|
}
|