Files
pyfragment/CHANGELOG.md
T
bohd4nx 8163ed1a9d feat: Add gift and number search functionality to FragmentClient
- Implemented `search_gifts` method for searching gifts in the Fragment marketplace.
- Implemented `search_numbers` method for searching anonymous Telegram numbers.
- Added new example scripts for searching gifts, numbers, and usernames.
- Updated HTML parsing logic to handle gift items and number listings.
- Added unit tests for the new search methods and updated existing tests for usernames and numbers.
- Removed obsolete test file for auction searches.
2026-03-25 18:01:22 +02:00

96 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to pyfragment are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project uses [Calendar Versioning](https://calver.org/) (`YYYY.MINOR.MICRO`).
---
## [Unreleased]
### Added
**Giveaways**
- `giveaway_stars(channel, winners, amount)` — run a Telegram Stars giveaway for a channel (15 winners, 5001 000 000 stars each); raises `UserNotFoundError` if the channel is not found on Fragment, `ConfigurationError` if `winners` or `amount` are out of range
- `giveaway_premium(channel, winners, months)` — run a Telegram Premium giveaway for a channel (124 000 winners, 3/6/12 months each); raises `UserNotFoundError` if the channel is not found on Fragment, `ConfigurationError` if `winners` or `months` are invalid
- `StarsGiveawayResult` and `PremiumGiveawayResult` result types
**Telegram Ads**
- `recharge_ads(account, amount)` — add funds to your own Telegram Ads account; `account` is the channel or bot username linked to your Ads account; raises `ConfigurationError` if `amount` is out of range (11 000 000 000 TON)
- `AdsRechargeResult` result type
**Marketplace**
- `search_usernames(query?, sort?, filter?, offset_id?)` — search the Fragment marketplace for Telegram usernames; `sort` is one of `"price_desc"`, `"price_asc"`, `"listed"`, `"ending"`; `filter` is one of `""`, `"auction"`, `"sale"`, `"sold"`; supports pagination via `offset_id`; returns parsed item dicts with `slug`, `name`, `status`, `price`, `date`
- `search_numbers(query?, sort?, filter?, offset_id?)` — search the Fragment marketplace for anonymous Telegram numbers; same `sort` / `filter` / `offset_id` semantics as `search_usernames`
- `search_gifts(query?, collection?, sort?, filter?, view?, attr?, offset?)` — search the Fragment gifts marketplace; `collection` is the gift collection slug (e.g. `"artisanbrick"`); `attr` accepts trait filters as `{"Model": ["Foosball"], "Backdrop": ["Celtic Blue"]}`; supports integer-based pagination via `offset`; returns parsed item dicts with `slug`, `name`, `status`, `price`, `date`
- `UsernamesResult`, `NumbersResult`, `GiftsResult` result types
**Raw API access**
- `FragmentClient.call(method, data, *, page_url)` — send a raw request to any Fragment API method without waiting for a library update
- `FRAGMENT_BASE_URL` constant — single source of truth for the Fragment base URL used across all page constants and headers
**Anonymous number management**
- `get_login_code(number)` — fetch the current pending login code for an anonymous number
- `toggle_login_codes(number, can_receive)` — enable or disable login code delivery for an anonymous number
- `terminate_sessions(number)` — terminate all active Telegram sessions for an anonymous number (two-step flow handled internally)
- `LoginCodeResult` and `TerminateSessionsResult` result types
- `AnonymousNumberError` exception — raised when a number is not owned or session termination fails
**Examples**
- `examples/giveaway_stars.py` — Stars giveaway with `UserNotFoundError` / `ConfigurationError` handling
- `examples/giveaway_premium.py` — Premium giveaway with `UserNotFoundError` / `ConfigurationError` handling
- `examples/call.py` — raw API call via `client.call()`
- `examples/anonymous_number.py` — login code fetch and session termination with `AnonymousNumberError` handling
- `examples/recharge_ads.py` — self-service Ads recharge with `ConfigurationError` / `WalletError` handling
- `examples/search_usernames.py` — username marketplace search with pagination
- `examples/search_numbers.py` — number marketplace search with pagination
- `examples/search_gifts.py` — gifts marketplace search with collection, attr, and pagination
### Changed
- All result types (`PremiumResult`, `StarsResult`, `StarsGiveawayResult`, `PremiumGiveawayResult`) now use a single unified `amount` field instead of `months`, `stars` — consistent API across every method
- `__repr__` on result types now includes the unit (`3 months`, `500 stars`) for clarity
- Method module files renamed to match their function: `premium.py``purchase_premium.py`, `stars.py``purchase_stars.py`, `ton.py``topup_ton.py`
- `timestamp` field removed from all result dataclasses
- All page URL constants (`STARS_PAGE`, `PREMIUM_PAGE`, etc.) now built from `FRAGMENT_BASE_URL` instead of hardcoded strings
- `STARS_REVENUE_PAGE` and `ADS_PAGE` constants replaced by a single `ADS_TOPUP_PAGE` shared by both `topup_ton` and `recharge_ads`
- `TransactionError` now includes an SSL hint when a broadcast fails due to certificate verification errors
- `TransactionError.DUPLICATE_SEQNO` — dedicated error raised after 3 failed attempts due to a `406 Duplicate msg_seqno` response from the TON network; broadcast is automatically retried (up to 2 retries, 2 s apart) before giving up
- All error message templates rewritten to follow a "what happened → why → what to do" pattern — every template is now actionable and includes a fix hint where applicable
---
## [2026.0.2] — 2026-03-20
### Added
- `timeout` parameter on `FragmentClient` (default `30.0` s) — passed through to every HTTP request
### Changed
- Cookie validation: narrowed type internally so no `# type: ignore` is needed in `FragmentClient.__init__`
- `WALLET_CLASSES` typed as `dict[str, Any]` so mypy resolves `from_mnemonic` correctly
- All four `examples/` files updated to `async with FragmentClient`, f-strings, and aligned error messages
- README usage section rewritten with a single comprehensive `async with` example
### Fixed
- mypy: missing return path in `process_transaction` after retry loop
- mypy: `cookies` union-attr error in `FragmentClient.__init__`
---
## [2026.0.1] — 2026-03-16
### Added
- Initial stable release of `pyfragment`
- `FragmentClient` — async client for the Fragment.com API with context manager support (`async with`)
- `purchase_premium(username, months)` — purchase Telegram Premium for any user (3, 6, or 12 months)
- `purchase_stars(username, amount)` — send Telegram Stars to any user (501,000,000)
- `topup_ton(username, amount)` — top up TON Ads balance (11,000,000,000 TON)
- `get_wallet()` — fetch wallet address and balance
- Support for TON wallet versions `V4R2` and `V5R1`
- Structured exception hierarchy (`FragmentError`, `ConfigurationError`, `CookieError`, etc.)
- `py.typed` marker — full PEP 561 typing support for type-checkers
- `__repr__` on all result types for readable debug output
[2026.0.2]: https://github.com/bohd4nx/pyfragment/releases/tag/v2026.0.2
[2026.0.1]: https://github.com/bohd4nx/pyfragment/releases/tag/v2026.0.1