import json from fragmentapi.methods.premium import gift_premium from fragmentapi.methods.stars import gift_stars from fragmentapi.methods.ton import topup_ton from fragmentapi.types import ( REQUIRED_COOKIE_KEYS, SUPPORTED_WALLET_VERSIONS, AdsTopupResult, ConfigError, CookiesError, PremiumResult, StarsResult, WalletVersion, ) class FragmentClient: """ Client for the Fragment.com API. Args: seed: 24-word mnemonic phrase for the TON wallet. api_key: Tonapi API key — get one at https://tonconsole.com. cookies: Fragment session cookies as a dict or JSON string. wallet_version: Wallet contract version — ``"V4R2"`` or ``"V5R1"`` (default). Raises: ConfigError: If ``seed``, ``api_key``, or ``wallet_version`` are missing or invalid. CookiesError: If ``cookies`` cannot be parsed or are missing required keys. Example:: client = FragmentClient( seed="word1 word2 ...", api_key="AAABBB...", cookies={"stel_ssid": "...", "stel_dt": "...", ...}, ) result = await client.gift_premium("@username", months=6) print(result.transaction_id) """ def __init__( self, seed: str, api_key: str, cookies: dict | str, wallet_version: str = "V5R1", ) -> None: missing = [name for name, val in (("seed", seed), ("api_key", api_key)) if not val or not str(val).strip()] if missing: raise ConfigError(ConfigError.MISSING_VARS.format(keys=", ".join(missing))) if isinstance(cookies, str): try: cookies = json.loads(cookies) except Exception as exc: raise CookiesError(CookiesError.READ_FAILED.format(exc=exc)) from exc missing_keys = [k for k in REQUIRED_COOKIE_KEYS if not str(cookies.get(k, "")).strip()] if missing_keys: raise CookiesError(CookiesError.MISSING_KEYS.format(keys=", ".join(missing_keys))) version = wallet_version.strip().upper() if version not in SUPPORTED_WALLET_VERSIONS: raise ConfigError( ConfigError.UNSUPPORTED_VERSION.format(version=version, supported=", ".join(sorted(SUPPORTED_WALLET_VERSIONS))) ) self.seed: str = seed.strip() self.api_key: str = api_key.strip() self.cookies: dict = cookies self.wallet_version: WalletVersion = version # type: ignore[assignment] async def gift_premium(self, username: str, months: int, show_sender: bool = True) -> PremiumResult: """Gift Telegram Premium to a user. Args: username: Recipient's Telegram username (with or without ``@``). months: Duration — ``3``, ``6``, or ``12``. show_sender: Show your name as the gift sender. Defaults to ``True``. Returns: :class:`PremiumResult` with ``transaction_id``, ``username``, ``months``, ``timestamp``. """ return await gift_premium(self, username, months, show_sender) async def gift_stars(self, username: str, amount: int, show_sender: bool = True) -> StarsResult: """Gift Telegram Stars to a user. Args: username: Recipient's Telegram username (with or without ``@``). amount: Number of stars — integer from ``50`` to ``1 000 000``. show_sender: Show your name as the gift sender. Defaults to ``True``. Returns: :class:`StarsResult` with ``transaction_id``, ``username``, ``stars``, ``timestamp``. """ return await gift_stars(self, username, amount, show_sender) async def topup_ton(self, username: str, amount: int, show_sender: bool = True) -> AdsTopupResult: """Top up Telegram Ads balance with TON. Args: username: Ads account username (with or without ``@``). amount: Amount in TON — integer from ``1`` to ``1 000 000 000``. show_sender: Show your name as the sender. Defaults to ``True``. Returns: :class:`AdsTopupResult` with ``transaction_id``, ``username``, ``amount``, ``timestamp``. """ return await topup_ton(self, username, amount, show_sender)