mirror of
https://github.com/bohd4nx/FragmentAPI.git
synced 2026-07-25 06:14:29 +00:00
docs: rewrite structure and humanize GitBook docs
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
name: Docs Branch Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [docs]
|
||||
pull_request:
|
||||
branches: [docs]
|
||||
|
||||
jobs:
|
||||
docs-tree:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Ensure docs structure exists
|
||||
run: |
|
||||
test -f docs/README.md
|
||||
test -f docs/SUMMARY.md
|
||||
test -d docs/getting-started
|
||||
test -d docs/client
|
||||
test -d docs/reference
|
||||
test -d docs/advanced
|
||||
@@ -0,0 +1 @@
|
||||
.DS_Store
|
||||
@@ -0,0 +1,6 @@
|
||||
# pyfragment docs branch
|
||||
|
||||
This branch is dedicated to GitBook content.
|
||||
|
||||
- Main docs source: docs/
|
||||
- Navigation: docs/SUMMARY.md
|
||||
@@ -0,0 +1,41 @@
|
||||
# pyfragment Documentation
|
||||
|
||||
`pyfragment` is an async Python client for [Fragment](https://fragment.com).
|
||||
|
||||
If you are integrating Fragment into a bot or backend, this docs set is meant to be practical, not theoretical.
|
||||
|
||||
**Recommended reading order:**
|
||||
|
||||
1. Install the package
|
||||
2. Configure `FragmentClient`
|
||||
3. Set up credentials and cookies
|
||||
4. Run the quick start
|
||||
5. Move to feature-specific flows
|
||||
|
||||
## Who this is for
|
||||
|
||||
- Python developers integrating Fragment into bots, services, and automation.
|
||||
- Teams that need predictable typed results and explicit error behavior.
|
||||
|
||||
**Important:** this library is not affiliated with Fragment or Telegram.
|
||||
|
||||
## Where to begin
|
||||
|
||||
1. [Installation](getting-started/installation.md)
|
||||
2. [Library and Configuration](getting-started/configuration.md)
|
||||
3. [Credentials and Cookies](getting-started/credentials-and-cookies.md)
|
||||
4. [Quick Start](getting-started/quickstart.md)
|
||||
|
||||
## Feature entry points
|
||||
|
||||
- Stars: [Purchase](client/stars/purchase.md), [Giveaway](client/stars/giveaway.md)
|
||||
- Premium: [Purchase](client/premium/purchase.md), [Giveaway](client/premium/giveaway.md)
|
||||
- Marketplace: [Overview](client/marketplace/overview.md), Ads: [Ads](client/ads.md)
|
||||
- Management: [Anonymous Numbers](client/anonymous-numbers.md)
|
||||
|
||||
## Additional references
|
||||
|
||||
- [Error Handling](reference/errors.md)
|
||||
- [Result Models](reference/models.md)
|
||||
- [Literal Types](reference/literals.md)
|
||||
- [Troubleshooting](advanced/troubleshooting.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# Table of contents
|
||||
|
||||
- [Start Here](getting-started/installation.md)
|
||||
- Getting Started
|
||||
- [Installation](getting-started/installation.md)
|
||||
- [Library and Configuration](getting-started/configuration.md)
|
||||
- [Credentials and Cookies](getting-started/credentials-and-cookies.md)
|
||||
- [Quick Start](getting-started/quickstart.md)
|
||||
- [Error Handling](reference/errors.md)
|
||||
- Client API
|
||||
- [Overview](client/overview.md)
|
||||
- Stars
|
||||
- [Purchase](client/stars/purchase.md)
|
||||
- [Giveaway](client/stars/giveaway.md)
|
||||
- Premium
|
||||
- [Purchase](client/premium/purchase.md)
|
||||
- [Giveaway](client/premium/giveaway.md)
|
||||
- [Ads](client/ads.md)
|
||||
- [Anonymous Numbers](client/anonymous-numbers.md)
|
||||
- Marketplace
|
||||
- [Overview](client/marketplace/overview.md)
|
||||
- [Search Usernames](client/marketplace/search-usernames.md)
|
||||
- [Search Numbers](client/marketplace/search-numbers.md)
|
||||
- [Search Gifts](client/marketplace/search-gifts.md)
|
||||
- [Raw API Calls](client/raw-call.md)
|
||||
- Reference
|
||||
- [Result Models](reference/models.md)
|
||||
- [Literal Types](reference/literals.md)
|
||||
- Advanced
|
||||
- [Cookie Extraction Details](advanced/cookies.md)
|
||||
- [Troubleshooting](advanced/troubleshooting.md)
|
||||
@@ -0,0 +1,24 @@
|
||||
# Cookie Extraction Details
|
||||
|
||||
`get_cookies_from_browser(browser)` reads Fragment cookies from local browser storage (via `rookiepy`).
|
||||
|
||||
This is the fastest way to start when you do not want manual cookie export.
|
||||
|
||||
Supported browsers are defined in constants and include:
|
||||
|
||||
- chrome, firefox, edge, brave,
|
||||
- arc, opera, opera_gx,
|
||||
- safari, vivaldi,
|
||||
- chromium variants.
|
||||
|
||||
Validation includes:
|
||||
|
||||
- required key presence,
|
||||
- non-empty values,
|
||||
- optional expiration check for `stel_ssid`.
|
||||
|
||||
**If any required cookie is empty or missing, extraction is treated as failed.**
|
||||
|
||||
If extraction fails, `CookieError` is raised with actionable details.
|
||||
|
||||
Use [Credentials and Cookies](../getting-started/credentials-and-cookies.md) for setup-first instructions.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Troubleshooting
|
||||
|
||||
When something breaks, start here. Most issues are caused by cookies, session state, or wallet balance.
|
||||
|
||||
## Auth/session errors
|
||||
|
||||
Symptoms:
|
||||
|
||||
- Fragment page hash cannot be extracted,
|
||||
- bad status loading Fragment pages,
|
||||
- missing request IDs.
|
||||
|
||||
Actions:
|
||||
|
||||
- re-login on fragment.com,
|
||||
- refresh cookies,
|
||||
- ensure all `stel_*` keys are present.
|
||||
- verify constructor payload in [Library and Configuration](../getting-started/configuration.md).
|
||||
|
||||
**Re-login + fresh cookies solves the majority of auth errors.**
|
||||
|
||||
## Cookie extraction errors
|
||||
|
||||
Symptoms:
|
||||
|
||||
- browser not supported,
|
||||
- cannot read browser profile,
|
||||
- required cookies not found.
|
||||
|
||||
Actions:
|
||||
|
||||
- install `pyfragment[browser]`,
|
||||
- close locked browser profiles,
|
||||
- use manual cookies if needed.
|
||||
|
||||
## Balance/transaction failures
|
||||
|
||||
Symptoms:
|
||||
|
||||
- low TON/USDT balance errors,
|
||||
- broadcast failures,
|
||||
- duplicate seqno retries.
|
||||
|
||||
Actions:
|
||||
|
||||
- keep TON reserve for fees,
|
||||
- ensure USDT is on the **Fragment-linked wallet**,
|
||||
- retry after short delay when seqno collisions happen.
|
||||
- check operation constraints in Stars/Premium/Ads method pages.
|
||||
|
||||
## SSL-related broadcast failures
|
||||
|
||||
If you get SSL-related transaction errors:
|
||||
|
||||
```bash
|
||||
pip install --upgrade certifi
|
||||
```
|
||||
|
||||
On macOS, also run Python's `Install Certificates.command` if needed.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Ads
|
||||
|
||||
Ads methods cover two different actions:
|
||||
|
||||
- sending TON to a user,
|
||||
- recharging your own Telegram Ads account.
|
||||
|
||||
## topup_ton
|
||||
|
||||
```python
|
||||
await client.topup_ton(
|
||||
username: str,
|
||||
amount: int,
|
||||
show_sender: bool = True,
|
||||
) -> AdsTopupResult
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `username`: recipient Telegram username
|
||||
- `amount`: integer from `1` to `1_000_000_000`
|
||||
- `show_sender`: sender visibility
|
||||
|
||||
**Important:** `amount` must be an integer in allowed range.
|
||||
|
||||
## recharge_ads
|
||||
|
||||
```python
|
||||
await client.recharge_ads(
|
||||
account: str,
|
||||
amount: int,
|
||||
) -> AdsRechargeResult
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `account`: channel/bot username linked to your ads account
|
||||
- `amount`: integer from `1` to `1_000_000_000`
|
||||
|
||||
## Returns
|
||||
|
||||
- `AdsTopupResult(transaction_id, username, amount)`
|
||||
- `AdsRechargeResult(transaction_id, amount)`
|
||||
|
||||
## Common errors
|
||||
|
||||
- `ConfigurationError`
|
||||
- `UserNotFoundError` (topup recipient)
|
||||
- `WalletError`
|
||||
- `VerificationError`
|
||||
|
||||
## Related flows
|
||||
|
||||
- [Stars Purchase](stars/purchase.md)
|
||||
- [Premium Purchase](premium/purchase.md)
|
||||
@@ -0,0 +1,45 @@
|
||||
# Anonymous Numbers
|
||||
|
||||
These methods help you manage login behavior and active sessions for anonymous numbers owned by your current account.
|
||||
|
||||
## get_login_code
|
||||
|
||||
```python
|
||||
await client.get_login_code(number: str) -> LoginCodeResult
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
- `number`
|
||||
- `code` (`None` if no pending code)
|
||||
- `active_sessions`
|
||||
|
||||
## toggle_login_codes
|
||||
|
||||
```python
|
||||
await client.toggle_login_codes(number: str, can_receive: bool) -> None
|
||||
```
|
||||
|
||||
Use `can_receive=True` to allow incoming login codes, or `False` to block them.
|
||||
|
||||
## terminate_sessions
|
||||
|
||||
```python
|
||||
await client.terminate_sessions(number: str) -> TerminateSessionsResult
|
||||
```
|
||||
|
||||
Returns:
|
||||
|
||||
- `number`
|
||||
- `message`
|
||||
|
||||
## Common errors
|
||||
|
||||
- `AnonymousNumberError.NOT_OWNED`
|
||||
- `AnonymousNumberError.TERMINATE_FAILED`
|
||||
|
||||
## Practical note
|
||||
|
||||
These methods operate only on numbers owned by the currently authorized Fragment account.
|
||||
|
||||
**If a number is not yours, requests will fail with `AnonymousNumberError`.**
|
||||
@@ -0,0 +1,31 @@
|
||||
# Marketplace Overview
|
||||
|
||||
Marketplace methods are exposed directly on `FragmentClient` and via `client.marketplace` service.
|
||||
|
||||
If you only need one thing: pick the method by asset type (username, number, gift), then paginate until `next_offset_id` or `next_offset` becomes `None`.
|
||||
|
||||
Available methods:
|
||||
|
||||
- [Search Usernames](search-usernames.md)
|
||||
- [Search Numbers](search-numbers.md)
|
||||
- [Search Gifts](search-gifts.md)
|
||||
|
||||
## Shared behavior
|
||||
|
||||
- All methods are async.
|
||||
- All methods call Fragment `searchAuctions` under the hood.
|
||||
- `sort` and `filter` are optional passthrough strings.
|
||||
|
||||
**These values are passed to Fragment as-is.** If Fragment changes accepted values, behavior can change too.
|
||||
|
||||
Common values used by Fragment pages:
|
||||
|
||||
- `sort`: `price_desc`, `price_asc`, `listed`, `ending`
|
||||
- `filter`: empty string, `auction`, `sale`, `sold`
|
||||
|
||||
## Pagination model
|
||||
|
||||
- Usernames and Numbers return `next_offset_id` (string)
|
||||
- Gifts return `next_offset` (integer)
|
||||
|
||||
Use these fields to request next pages.
|
||||
@@ -0,0 +1,75 @@
|
||||
# Search Gifts
|
||||
|
||||
This endpoint is the most flexible marketplace search and supports collection, traits, and pagination.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.search_gifts(
|
||||
query: str = "",
|
||||
collection: str | None = None,
|
||||
sort: str | None = None,
|
||||
filter: str | None = None,
|
||||
view: str | None = None,
|
||||
attr: dict[str, list[str]] | None = None,
|
||||
offset: int | None = None,
|
||||
) -> GiftsResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `query`: search text (empty string for broad listing)
|
||||
- `collection`: collection slug (for example `plushpepe`, `swisswatch`)
|
||||
- `sort`: optional sort key passed to Fragment
|
||||
- `filter`: optional listing filter passed to Fragment
|
||||
- `view`: optional UI/view mode passed to Fragment
|
||||
- `attr`: optional trait filters where key is trait name and value is list of allowed values
|
||||
- `offset`: page offset for next page
|
||||
|
||||
**`attr` is ideal for narrowing results by visual or rarity traits.**
|
||||
|
||||
## Sorting values
|
||||
|
||||
Common values accepted by Fragment:
|
||||
|
||||
- `price_desc`
|
||||
- `price_asc`
|
||||
- `listed`
|
||||
- `ending`
|
||||
|
||||
## Filter values
|
||||
|
||||
Common values accepted by Fragment:
|
||||
|
||||
- empty string
|
||||
- `auction`
|
||||
- `sale`
|
||||
- `sold`
|
||||
|
||||
## Attribute filter format
|
||||
|
||||
`attr` is encoded into request fields in this form:
|
||||
|
||||
- `attr[trait_name] = ["value1", "value2"]`
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
attr={
|
||||
"model": ["gold", "silver"],
|
||||
"rarity": ["rare"],
|
||||
}
|
||||
```
|
||||
|
||||
In requests, each trait is sent as `attr[trait]` with a list of values.
|
||||
|
||||
## Return type
|
||||
|
||||
`GiftsResult` contains:
|
||||
|
||||
- `items: list[dict[str, Any]]`
|
||||
- `next_offset: int | None`
|
||||
|
||||
## Pagination
|
||||
|
||||
If `next_offset` is not `None`, pass it back as `offset` to load the next page.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Search Numbers
|
||||
|
||||
Use this endpoint to search anonymous Telegram number listings.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.search_numbers(
|
||||
query: str = "",
|
||||
sort: str | None = None,
|
||||
filter: str | None = None,
|
||||
offset_id: str | None = None,
|
||||
) -> NumbersResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `query`: digits or text to match number listings
|
||||
- `sort`: optional sort key passed to Fragment
|
||||
- `filter`: optional listing filter passed to Fragment
|
||||
- `offset_id`: page cursor for next page
|
||||
|
||||
`query` can be partial digits (for example `"888"`) when you need pattern-based discovery.
|
||||
|
||||
## Sorting values
|
||||
|
||||
Common values accepted by Fragment:
|
||||
|
||||
- `price_desc`
|
||||
- `price_asc`
|
||||
- `listed`
|
||||
- `ending`
|
||||
|
||||
## Filter values
|
||||
|
||||
Common values accepted by Fragment:
|
||||
|
||||
- empty string
|
||||
- `auction`
|
||||
- `sale`
|
||||
- `sold`
|
||||
|
||||
## Return type
|
||||
|
||||
`NumbersResult` contains:
|
||||
|
||||
- `items: list[dict[str, Any]]`
|
||||
- `next_offset_id: str | None`
|
||||
|
||||
## Pagination
|
||||
|
||||
If `next_offset_id` is not `None`, pass it back as `offset_id` to load the next page.
|
||||
|
||||
Keep requesting pages until `next_offset_id` becomes `None`.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Search Usernames
|
||||
|
||||
Use this endpoint to discover Telegram usernames listed on Fragment.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.search_usernames(
|
||||
query: str = "",
|
||||
sort: str | None = None,
|
||||
filter: str | None = None,
|
||||
offset_id: str | None = None,
|
||||
) -> UsernamesResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `query`: search text (empty string means broad listing)
|
||||
- `sort`: optional sort key passed to Fragment
|
||||
- `filter`: optional listing filter passed to Fragment
|
||||
- `offset_id`: page cursor for next page
|
||||
|
||||
For broad browsing, use empty `query` and set sorting only.
|
||||
|
||||
## Sorting values
|
||||
|
||||
Common values accepted by Fragment:
|
||||
|
||||
- `price_desc`
|
||||
- `price_asc`
|
||||
- `listed`
|
||||
- `ending`
|
||||
|
||||
## Filter values
|
||||
|
||||
Common values accepted by Fragment:
|
||||
|
||||
- empty string
|
||||
- `auction`
|
||||
- `sale`
|
||||
- `sold`
|
||||
|
||||
## Return type
|
||||
|
||||
`UsernamesResult` contains:
|
||||
|
||||
- `items: list[dict[str, Any]]`
|
||||
- `next_offset_id: str | None`
|
||||
|
||||
## Pagination
|
||||
|
||||
If `next_offset_id` is not `None`, pass it back as `offset_id` to load the next page.
|
||||
|
||||
This is cursor pagination, so do not try to calculate offsets manually.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Client Overview
|
||||
|
||||
`FragmentClient` is the main API surface.
|
||||
|
||||
You can call methods directly on the client or use grouped services.
|
||||
|
||||
Grouped service wrappers:
|
||||
|
||||
- `client.purchases`
|
||||
- `client.giveaways`
|
||||
- `client.ads`
|
||||
- `client.anonymous_numbers`
|
||||
- `client.marketplace`
|
||||
- `client.tonapi`
|
||||
|
||||
Main async methods on `FragmentClient`:
|
||||
|
||||
- `purchase_stars(...)`
|
||||
- `purchase_premium(...)`
|
||||
- `giveaway_stars(...)`
|
||||
- `giveaway_premium(...)`
|
||||
- `topup_ton(...)`
|
||||
- `recharge_ads(...)`
|
||||
- `get_wallet()`
|
||||
- `get_login_code(...)`
|
||||
- `toggle_login_codes(...)`
|
||||
- `terminate_sessions(...)`
|
||||
- `search_usernames(...)`
|
||||
- `search_numbers(...)`
|
||||
- `search_gifts(...)`
|
||||
- `call(...)`
|
||||
|
||||
All methods are async and should be used inside `async with FragmentClient(...) as client:`.
|
||||
|
||||
## Flow map
|
||||
|
||||
- Stars: [Purchase](stars/purchase.md), [Giveaway](stars/giveaway.md)
|
||||
- Premium: [Purchase](premium/purchase.md), [Giveaway](premium/giveaway.md)
|
||||
- Ads: [Ads operations](ads.md)
|
||||
- Utility operations: [Anonymous Numbers](anonymous-numbers.md), [Marketplace](marketplace/overview.md), [Raw API Calls](raw-call.md)
|
||||
|
||||
**If you are new to the library, start with Stars Purchase or Wallet read (`get_wallet`) first.**
|
||||
@@ -0,0 +1,34 @@
|
||||
# Premium Giveaway
|
||||
|
||||
Use this method to run a Telegram Premium giveaway for your channel.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.giveaway_premium(
|
||||
channel: str,
|
||||
winners: int,
|
||||
months: int = 3,
|
||||
payment_method: PaymentMethod = "ton",
|
||||
) -> PremiumGiveawayResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `channel`: accepts `@channel`, `channel`, or `https://t.me/channel`
|
||||
- `winners`: integer from `1` to `24_000`
|
||||
- `months`: one of `3`, `6`, `12`
|
||||
- `payment_method`: `"ton"` or `"usdt_ton"`
|
||||
|
||||
**`winners` must be a positive integer, and large values can increase total cost significantly.**
|
||||
|
||||
## Return
|
||||
|
||||
- `PremiumGiveawayResult(transaction_id, channel, winners, amount)`
|
||||
|
||||
## Typical errors
|
||||
|
||||
- `ConfigurationError`
|
||||
- `UserNotFoundError`
|
||||
- `WalletError`
|
||||
- `VerificationError`
|
||||
@@ -0,0 +1,34 @@
|
||||
# Premium Purchase
|
||||
|
||||
Use this method to gift Telegram Premium to a specific user.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.purchase_premium(
|
||||
username: str,
|
||||
months: int,
|
||||
show_sender: bool = True,
|
||||
payment_method: PaymentMethod = "ton",
|
||||
) -> PremiumResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `username`: accepts `@username`, `username`, or `https://t.me/username`
|
||||
- `months`: one of `3`, `6`, `12`
|
||||
- `show_sender`: controls sender visibility on recipient side
|
||||
- `payment_method`: `"ton"` or `"usdt_ton"`
|
||||
|
||||
**`months` only supports `3`, `6`, or `12`.**
|
||||
|
||||
## Return
|
||||
|
||||
- `PremiumResult(transaction_id, username, amount)`
|
||||
|
||||
## Typical errors
|
||||
|
||||
- `ConfigurationError`
|
||||
- `UserNotFoundError`
|
||||
- `WalletError`
|
||||
- `VerificationError`
|
||||
@@ -0,0 +1,32 @@
|
||||
# Raw API Calls
|
||||
|
||||
Use `client.call()` when you need a Fragment API method that does not yet have a dedicated wrapper.
|
||||
|
||||
```python
|
||||
result = await client.call(
|
||||
"searchPremiumGiftRecipient",
|
||||
{"query": "@username", "months": 3},
|
||||
page_url="https://fragment.com/premium/gift",
|
||||
)
|
||||
```
|
||||
|
||||
Signature:
|
||||
|
||||
```python
|
||||
await client.call(
|
||||
method: str,
|
||||
data: dict[str, Any] | None = None,
|
||||
*,
|
||||
page_url: str = "https://fragment.com",
|
||||
) -> dict[str, Any]
|
||||
```
|
||||
|
||||
Use this carefully:
|
||||
|
||||
- request/response shape is Fragment-defined,
|
||||
- undocumented methods can change without notice,
|
||||
- you are responsible for validating returned fields.
|
||||
|
||||
## Recommended approach
|
||||
|
||||
Use dedicated wrappers first, and fallback to `call()` only for missing API surface.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Stars Giveaway
|
||||
|
||||
Use this method to run a Stars giveaway for a channel audience.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.giveaway_stars(
|
||||
channel: str,
|
||||
winners: int,
|
||||
amount: int,
|
||||
payment_method: PaymentMethod = "ton",
|
||||
) -> StarsGiveawayResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `channel`: accepts `@channel`, `channel`, or `https://t.me/channel`
|
||||
- `winners`: integer from `1` to `5`
|
||||
- `amount`: integer from `500` to `1_000_000` (per winner)
|
||||
- `payment_method`: `"ton"` or `"usdt_ton"`
|
||||
|
||||
**Each winner receives the full `amount` value.**
|
||||
|
||||
## Return
|
||||
|
||||
- `StarsGiveawayResult(transaction_id, channel, winners, amount)`
|
||||
|
||||
## Typical errors
|
||||
|
||||
- `ConfigurationError`
|
||||
- `UserNotFoundError`
|
||||
- `WalletError`
|
||||
- `VerificationError`
|
||||
@@ -0,0 +1,34 @@
|
||||
# Stars Purchase
|
||||
|
||||
Use this method to send Telegram Stars directly to a user.
|
||||
|
||||
## Method
|
||||
|
||||
```python
|
||||
await client.purchase_stars(
|
||||
username: str,
|
||||
amount: int,
|
||||
show_sender: bool = True,
|
||||
payment_method: PaymentMethod = "ton",
|
||||
) -> StarsResult
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `username`: accepts `@username`, `username`, or `https://t.me/username`
|
||||
- `amount`: integer from `50` to `1_000_000`
|
||||
- `show_sender`: controls sender visibility on recipient side
|
||||
- `payment_method`: `"ton"` or `"usdt_ton"`
|
||||
|
||||
**Amount must be between `50` and `1_000_000`.**
|
||||
|
||||
## Return
|
||||
|
||||
- `StarsResult(transaction_id, username, amount)`
|
||||
|
||||
## Typical errors
|
||||
|
||||
- `ConfigurationError`: invalid amount or payment method
|
||||
- `UserNotFoundError`: target user not found
|
||||
- `WalletError`: insufficient balance or wallet-side issue
|
||||
- `VerificationError`: verification/KYC required for operation
|
||||
@@ -0,0 +1,69 @@
|
||||
# Library and Configuration
|
||||
|
||||
Main entry point of the library is `FragmentClient`.
|
||||
|
||||
```python
|
||||
FragmentClient(
|
||||
seed: str,
|
||||
api_key: str,
|
||||
cookies: dict[str, Any] | str,
|
||||
wallet_version: str = "V5R1",
|
||||
timeout: float = 30.0,
|
||||
)
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
- `seed`: wallet mnemonic (**12, 18, or 24 words**)
|
||||
- `api_key`: Tonapi key from https://tonconsole.com
|
||||
- `cookies`: Fragment cookies as a dictionary or JSON string
|
||||
- `wallet_version`: `"V4R2"` or `"V5R1"`
|
||||
- `timeout`: request timeout in seconds
|
||||
|
||||
**If `api_key` is too short or cookies are incomplete, initialization fails immediately.**
|
||||
|
||||
## Required cookies
|
||||
|
||||
- `stel_ssid`
|
||||
- `stel_dt`
|
||||
- `stel_token`
|
||||
- `stel_ton_token`
|
||||
|
||||
## Minimal initialization pattern
|
||||
|
||||
```python
|
||||
from pyfragment import FragmentClient
|
||||
|
||||
client = FragmentClient(
|
||||
seed="word1 word2 ... word24",
|
||||
api_key="YOUR_TONAPI_KEY",
|
||||
cookies={
|
||||
"stel_ssid": "...",
|
||||
"stel_dt": "...",
|
||||
"stel_token": "...",
|
||||
"stel_ton_token": "...",
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Use it inside async context manager:
|
||||
|
||||
```python
|
||||
async with client:
|
||||
wallet = await client.get_wallet()
|
||||
```
|
||||
|
||||
You can also create the client directly inside `async with` if you prefer one-block setup.
|
||||
|
||||
## Validation behavior
|
||||
|
||||
At initialization, library validates:
|
||||
|
||||
- seed format,
|
||||
- cookie shape and required keys,
|
||||
- supported wallet version,
|
||||
- parseability of cookie JSON strings.
|
||||
|
||||
Constructor-level issues are raised as `ConfigurationError` or `CookieError`.
|
||||
|
||||
**Tip:** keep validation failures visible in logs during initial integration. They save a lot of debugging time.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Credentials and Cookies
|
||||
|
||||
This page covers the three things you need before making real requests: Tonapi key, wallet seed, and Fragment cookies.
|
||||
|
||||
## Tonapi key
|
||||
|
||||
Generate an API key at https://tonconsole.com.
|
||||
|
||||
## Seed phrase
|
||||
|
||||
Use your TON wallet mnemonic.
|
||||
|
||||
- **Keep it private.**
|
||||
- **Never log it or commit it to git.**
|
||||
|
||||
## Fragment cookies
|
||||
|
||||
You must be logged in to Fragment.
|
||||
|
||||
### Option 1: automatic extraction
|
||||
|
||||
```python
|
||||
from pyfragment import get_cookies_from_browser
|
||||
|
||||
cookie_result = get_cookies_from_browser("chrome")
|
||||
cookies = cookie_result.cookies
|
||||
```
|
||||
|
||||
`cookie_result` is `CookieResult`:
|
||||
|
||||
- `cookies`: `dict[str, str]`
|
||||
- `expires`: ISO string or `None`
|
||||
|
||||
### Option 2: manual export
|
||||
|
||||
Export the four required Fragment cookies and pass them directly as dict or JSON string.
|
||||
|
||||
Required keys:
|
||||
|
||||
- `stel_ssid`
|
||||
- `stel_dt`
|
||||
- `stel_token`
|
||||
- `stel_ton_token`
|
||||
|
||||
## Common auth failures
|
||||
|
||||
- expired session cookies,
|
||||
- not logged in on fragment.com,
|
||||
- missing `stel_*` keys,
|
||||
- stale cookies from another browser/profile.
|
||||
|
||||
When this happens, re-login on fragment.com and refresh cookies first. It solves most auth issues.
|
||||
|
||||
## Next step
|
||||
|
||||
Proceed to [Quick Start](quickstart.md).
|
||||
@@ -0,0 +1,35 @@
|
||||
# Installation
|
||||
|
||||
You can be up and running in under a minute.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.10+
|
||||
|
||||
## Install from PyPI
|
||||
|
||||
```bash
|
||||
pip install pyfragment
|
||||
```
|
||||
|
||||
## Install latest dev branch
|
||||
|
||||
```bash
|
||||
pip install git+https://github.com/bohd4nx/pyfragment.git@dev
|
||||
```
|
||||
|
||||
## Optional browser cookie extraction support
|
||||
|
||||
If you want automatic cookie extraction from local browser profiles:
|
||||
|
||||
```bash
|
||||
pip install "pyfragment[browser]"
|
||||
```
|
||||
|
||||
This installs `rookiepy`, used by `get_cookies_from_browser()`.
|
||||
|
||||
**Use this extra if you do not want to copy cookies manually.**
|
||||
|
||||
## Next step
|
||||
|
||||
After installation, continue with [Library and Configuration](configuration.md).
|
||||
@@ -0,0 +1,36 @@
|
||||
# Quick Start
|
||||
|
||||
Use this minimal example to verify that your credentials, cookies, and wallet setup are correct.
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
|
||||
from pyfragment import FragmentClient
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async with FragmentClient(
|
||||
seed="word1 word2 ... word24",
|
||||
api_key="YOUR_TONAPI_KEY",
|
||||
cookies={
|
||||
"stel_ssid": "...",
|
||||
"stel_dt": "...",
|
||||
"stel_token": "...",
|
||||
"stel_ton_token": "...",
|
||||
},
|
||||
) as client:
|
||||
wallet = await client.get_wallet()
|
||||
print(wallet)
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
If this script returns wallet data, your setup is healthy.
|
||||
|
||||
Then move to feature pages:
|
||||
|
||||
- Stars: [Purchase](../client/stars/purchase.md), [Giveaway](../client/stars/giveaway.md)
|
||||
- Premium: [Purchase](../client/premium/purchase.md), [Giveaway](../client/premium/giveaway.md)
|
||||
- [Ads](../client/ads.md)
|
||||
- [Anonymous Numbers](../client/anonymous-numbers.md)
|
||||
- [Marketplace](../client/marketplace/overview.md)
|
||||
@@ -0,0 +1,53 @@
|
||||
# Error Handling
|
||||
|
||||
Good error handling is the difference between a stable integration and random production failures.
|
||||
|
||||
## Exception hierarchy
|
||||
|
||||
- `FragmentError`
|
||||
- `ClientError`
|
||||
- `ConfigurationError`
|
||||
- `CookieError`
|
||||
- `FragmentAPIError`
|
||||
- `FragmentPageError`
|
||||
- `UserNotFoundError`
|
||||
- `AnonymousNumberError`
|
||||
- `TransactionError`
|
||||
- `ParseError`
|
||||
- `VerificationError`
|
||||
- `OperationError`
|
||||
- `WalletError`
|
||||
- `UnexpectedError`
|
||||
|
||||
## Recommended handling pattern
|
||||
|
||||
```python
|
||||
from pyfragment import ConfigurationError, FragmentError, UserNotFoundError, WalletError
|
||||
|
||||
try:
|
||||
result = await client.purchase_stars("@username", amount=500)
|
||||
except UserNotFoundError:
|
||||
# recipient does not exist on Fragment
|
||||
...
|
||||
except WalletError:
|
||||
# insufficient balance or wallet-side issue
|
||||
...
|
||||
except ConfigurationError:
|
||||
# invalid local input
|
||||
...
|
||||
except FragmentError:
|
||||
# any other library-level failure
|
||||
...
|
||||
```
|
||||
|
||||
**Catch specific errors first, then fallback to `FragmentError`.**
|
||||
|
||||
## Method-to-error mapping
|
||||
|
||||
- Stars/Premium purchase and giveaway: `ConfigurationError`, `UserNotFoundError`, `WalletError`, `VerificationError`
|
||||
- Ads operations: `ConfigurationError`, `UserNotFoundError`, `WalletError`, `VerificationError`
|
||||
- Cookies/auth setup: `CookieError`, `ConfigurationError`, `FragmentPageError`
|
||||
|
||||
## Canonical messages
|
||||
|
||||
See `pyfragment/exceptions.py` for source-of-truth message templates.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Literal Types
|
||||
|
||||
These literals describe accepted string values for key method parameters.
|
||||
|
||||
## PaymentMethod
|
||||
|
||||
```python
|
||||
PaymentMethod = Literal["ton", "usdt_ton"]
|
||||
```
|
||||
|
||||
## WalletVersion
|
||||
|
||||
```python
|
||||
WalletVersion = Literal["V4R2", "V5R1"]
|
||||
```
|
||||
|
||||
These literals are exported from `pyfragment.models.enums` and `pyfragment.models`.
|
||||
|
||||
## Usage notes
|
||||
|
||||
- Use `PaymentMethod` for purchase and giveaway operations.
|
||||
- Use `WalletVersion` when configuring `FragmentClient`.
|
||||
|
||||
**Passing unsupported values raises `ConfigurationError`.**
|
||||
@@ -0,0 +1,31 @@
|
||||
# Result Models
|
||||
|
||||
Every high-level method returns a typed model, so you can rely on predictable fields instead of raw payload parsing.
|
||||
|
||||
Exported result models:
|
||||
|
||||
- `CookieResult(cookies, expires)`
|
||||
- `StarsResult(transaction_id, username, amount)`
|
||||
- `PremiumResult(transaction_id, username, amount)`
|
||||
- `AdsTopupResult(transaction_id, username, amount)`
|
||||
- `AdsRechargeResult(transaction_id, amount)`
|
||||
- `StarsGiveawayResult(transaction_id, channel, winners, amount)`
|
||||
- `PremiumGiveawayResult(transaction_id, channel, winners, amount)`
|
||||
- `WalletInfo(address, state, ton_balance, usdt_balance)`
|
||||
- `LoginCodeResult(number, code, active_sessions)`
|
||||
- `TerminateSessionsResult(number, message)`
|
||||
- `UsernamesResult(items, next_offset_id)`
|
||||
- `NumbersResult(items, next_offset_id)`
|
||||
- `GiftsResult(items, next_offset)`
|
||||
|
||||
Most high-level methods return one of these dataclasses.
|
||||
|
||||
## Where they are used
|
||||
|
||||
- Stars/Premium purchase: `StarsResult`, `PremiumResult`
|
||||
- Stars/Premium giveaway: `StarsGiveawayResult`, `PremiumGiveawayResult`
|
||||
- Ads: `AdsTopupResult`, `AdsRechargeResult`
|
||||
- Wallet and utility: `WalletInfo`, `LoginCodeResult`, `TerminateSessionsResult`
|
||||
- Marketplace search: `UsernamesResult`, `NumbersResult`, `GiftsResult`
|
||||
|
||||
**Use these models directly in your app layer and avoid passing raw dictionaries around.**
|
||||
Reference in New Issue
Block a user