pyfragment 2026.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyfragment-2026.0.1/.github/ISSUE_TEMPLATE/bug.yaml +101 -0
- pyfragment-2026.0.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
- pyfragment-2026.0.1/.github/ISSUE_TEMPLATE/feature.yaml +51 -0
- pyfragment-2026.0.1/.github/PULL_REQUEST_TEMPLATE.md +34 -0
- pyfragment-2026.0.1/.github/dependabot.yml +19 -0
- pyfragment-2026.0.1/.github/workflows/ci.yml +50 -0
- pyfragment-2026.0.1/.github/workflows/publish.yml +101 -0
- pyfragment-2026.0.1/.gitignore +39 -0
- pyfragment-2026.0.1/CHANGELOG.md +24 -0
- pyfragment-2026.0.1/LICENSE +21 -0
- pyfragment-2026.0.1/PKG-INFO +208 -0
- pyfragment-2026.0.1/README.md +174 -0
- pyfragment-2026.0.1/examples/get_wallet.py +40 -0
- pyfragment-2026.0.1/examples/purchase_premium.py +45 -0
- pyfragment-2026.0.1/examples/purchase_stars.py +45 -0
- pyfragment-2026.0.1/examples/topup_ton.py +48 -0
- pyfragment-2026.0.1/fragment.svg +1 -0
- pyfragment-2026.0.1/pyfragment/__init__.py +51 -0
- pyfragment-2026.0.1/pyfragment/client.py +146 -0
- pyfragment-2026.0.1/pyfragment/methods/__init__.py +5 -0
- pyfragment-2026.0.1/pyfragment/methods/premium.py +120 -0
- pyfragment-2026.0.1/pyfragment/methods/stars.py +107 -0
- pyfragment-2026.0.1/pyfragment/methods/ton.py +107 -0
- pyfragment-2026.0.1/pyfragment/py.typed +0 -0
- pyfragment-2026.0.1/pyfragment/types/__init__.py +62 -0
- pyfragment-2026.0.1/pyfragment/types/constants.py +55 -0
- pyfragment-2026.0.1/pyfragment/types/exceptions.py +109 -0
- pyfragment-2026.0.1/pyfragment/types/results.py +55 -0
- pyfragment-2026.0.1/pyfragment/utils/__init__.py +18 -0
- pyfragment-2026.0.1/pyfragment/utils/decoder.py +35 -0
- pyfragment-2026.0.1/pyfragment/utils/http.py +134 -0
- pyfragment-2026.0.1/pyfragment/utils/wallet.py +135 -0
- pyfragment-2026.0.1/pyproject.toml +70 -0
- pyfragment-2026.0.1/requirements-dev.txt +1 -0
- pyfragment-2026.0.1/requirements.txt +1 -0
- pyfragment-2026.0.1/tests/001_test_decode.py +40 -0
- pyfragment-2026.0.1/tests/002_test_client.py +113 -0
- pyfragment-2026.0.1/tests/003_test_hash.py +17 -0
- pyfragment-2026.0.1/tests/004_test_balance.py +127 -0
- pyfragment-2026.0.1/tests/005_test_methods.py +65 -0
- pyfragment-2026.0.1/tests/__init__.py +0 -0
- pyfragment-2026.0.1/tests/conftest.py +17 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report an issue or unexpected behavior in pyfragment.
|
|
3
|
+
labels:
|
|
4
|
+
- bug
|
|
5
|
+
body:
|
|
6
|
+
- type: checkboxes
|
|
7
|
+
attributes:
|
|
8
|
+
label: Checklist
|
|
9
|
+
options:
|
|
10
|
+
- label: I am sure the error is coming from pyfragment code
|
|
11
|
+
required: true
|
|
12
|
+
- label: I have searched the issue tracker for similar bug reports, including closed ones
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: markdown
|
|
16
|
+
attributes:
|
|
17
|
+
value: |
|
|
18
|
+
## Context
|
|
19
|
+
Please provide as much detail as possible to help us reproduce and fix the issue.
|
|
20
|
+
|
|
21
|
+
- type: input
|
|
22
|
+
attributes:
|
|
23
|
+
label: Operating system
|
|
24
|
+
placeholder: e.g. Ubuntu 22.04 / macOS 14 / Windows 11
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: input
|
|
29
|
+
attributes:
|
|
30
|
+
label: Python version
|
|
31
|
+
description: Run `python --version` inside your virtualenv
|
|
32
|
+
placeholder: e.g. 3.12.3
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: input
|
|
37
|
+
attributes:
|
|
38
|
+
label: pyfragment version
|
|
39
|
+
description: Run `pip show pyfragment` inside your virtualenv
|
|
40
|
+
placeholder: e.g. 2026.1.0
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
43
|
+
|
|
44
|
+
- type: textarea
|
|
45
|
+
attributes:
|
|
46
|
+
label: Expected behavior
|
|
47
|
+
description: Describe what you expected to happen.
|
|
48
|
+
placeholder: e.g. Stars should be purchased and StarsResult returned.
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
|
|
52
|
+
- type: textarea
|
|
53
|
+
attributes:
|
|
54
|
+
label: Current behavior
|
|
55
|
+
description: Describe what is actually happening.
|
|
56
|
+
placeholder: e.g. ParseError is raised with status 400.
|
|
57
|
+
validations:
|
|
58
|
+
required: true
|
|
59
|
+
|
|
60
|
+
- type: textarea
|
|
61
|
+
attributes:
|
|
62
|
+
label: Steps to reproduce
|
|
63
|
+
description: Minimal steps that reproduce the issue.
|
|
64
|
+
placeholder: |
|
|
65
|
+
1. Create FragmentClient with valid credentials
|
|
66
|
+
2. Call purchase_stars("@username", amount=100)
|
|
67
|
+
3. See error
|
|
68
|
+
validations:
|
|
69
|
+
required: true
|
|
70
|
+
|
|
71
|
+
- type: textarea
|
|
72
|
+
attributes:
|
|
73
|
+
label: Code example
|
|
74
|
+
description: Provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) if applicable.
|
|
75
|
+
placeholder: |
|
|
76
|
+
import asyncio
|
|
77
|
+
from pyfragment import FragmentClient
|
|
78
|
+
|
|
79
|
+
async def main():
|
|
80
|
+
client = FragmentClient(...)
|
|
81
|
+
result = await client.purchase_stars("@username", amount=100)
|
|
82
|
+
|
|
83
|
+
asyncio.run(main())
|
|
84
|
+
render: python
|
|
85
|
+
|
|
86
|
+
- type: textarea
|
|
87
|
+
attributes:
|
|
88
|
+
label: Traceback / logs
|
|
89
|
+
description: Paste the full traceback or relevant logs.
|
|
90
|
+
placeholder: |
|
|
91
|
+
Traceback (most recent call last):
|
|
92
|
+
File "main.py", line 7, in main
|
|
93
|
+
...
|
|
94
|
+
pyfragment.types.ParseError: ...
|
|
95
|
+
render: sh
|
|
96
|
+
|
|
97
|
+
- type: textarea
|
|
98
|
+
attributes:
|
|
99
|
+
label: Additional information
|
|
100
|
+
description: Anything else that might help us diagnose the problem.
|
|
101
|
+
placeholder: e.g. Only happens with V5R1 wallet version.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an improvement or new feature for pyfragment.
|
|
3
|
+
labels:
|
|
4
|
+
- enhancement
|
|
5
|
+
body:
|
|
6
|
+
- type: dropdown
|
|
7
|
+
attributes:
|
|
8
|
+
label: pyfragment version
|
|
9
|
+
description: Which version are you running?
|
|
10
|
+
options:
|
|
11
|
+
- latest
|
|
12
|
+
- older
|
|
13
|
+
- n/a
|
|
14
|
+
validations:
|
|
15
|
+
required: true
|
|
16
|
+
|
|
17
|
+
- type: textarea
|
|
18
|
+
attributes:
|
|
19
|
+
label: Problem
|
|
20
|
+
description: Is your request related to a specific problem? Describe it.
|
|
21
|
+
placeholder: e.g. There is no way to check my current TON balance before sending.
|
|
22
|
+
validations:
|
|
23
|
+
required: true
|
|
24
|
+
|
|
25
|
+
- type: textarea
|
|
26
|
+
attributes:
|
|
27
|
+
label: Proposed solution
|
|
28
|
+
description: Describe what you would like to see added or changed.
|
|
29
|
+
placeholder: e.g. Add a get_balance() method to FragmentClient.
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
|
|
33
|
+
- type: textarea
|
|
34
|
+
attributes:
|
|
35
|
+
label: Alternatives considered
|
|
36
|
+
description: Any workarounds or alternative approaches you have thought of.
|
|
37
|
+
placeholder: e.g. I manually call the Fragment API, but it's not ergonomic.
|
|
38
|
+
|
|
39
|
+
- type: textarea
|
|
40
|
+
attributes:
|
|
41
|
+
label: Code example
|
|
42
|
+
description: A short example demonstrating the desired API, if applicable.
|
|
43
|
+
placeholder: |
|
|
44
|
+
balance = await client.get_balance()
|
|
45
|
+
print(balance.ton)
|
|
46
|
+
render: python
|
|
47
|
+
|
|
48
|
+
- type: textarea
|
|
49
|
+
attributes:
|
|
50
|
+
label: Additional information
|
|
51
|
+
description: Any other context, screenshots, or references.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Description
|
|
2
|
+
|
|
3
|
+
Please include a summary of the change and which issue is fixed.
|
|
4
|
+
Include relevant motivation and context.
|
|
5
|
+
|
|
6
|
+
Fixes # (issue)
|
|
7
|
+
|
|
8
|
+
## Type of change
|
|
9
|
+
|
|
10
|
+
- [ ] Documentation (typos, examples, or any docs update)
|
|
11
|
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
|
12
|
+
- [ ] New feature (non-breaking change which adds functionality)
|
|
13
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
|
14
|
+
- [ ] This change requires a documentation update
|
|
15
|
+
|
|
16
|
+
## How has this been tested?
|
|
17
|
+
|
|
18
|
+
Describe the tests you ran to verify the change and list any relevant details.
|
|
19
|
+
|
|
20
|
+
- [ ] Existing tests pass (`pytest`)
|
|
21
|
+
- [ ] New tests added for this change
|
|
22
|
+
|
|
23
|
+
**Test configuration:**
|
|
24
|
+
* OS:
|
|
25
|
+
* Python version:
|
|
26
|
+
* pyfragment version:
|
|
27
|
+
|
|
28
|
+
## Checklist
|
|
29
|
+
|
|
30
|
+
- [ ] My code follows the style guidelines of this project
|
|
31
|
+
- [ ] I have performed a self-review of my own code
|
|
32
|
+
- [ ] I have updated documentation where necessary
|
|
33
|
+
- [ ] I have added tests that prove my fix or feature works
|
|
34
|
+
- [ ] All new and existing tests pass locally
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
day: "monday"
|
|
8
|
+
open-pull-requests-limit: 5
|
|
9
|
+
labels:
|
|
10
|
+
- "dependencies"
|
|
11
|
+
|
|
12
|
+
- package-ecosystem: "github-actions"
|
|
13
|
+
directory: "/"
|
|
14
|
+
schedule:
|
|
15
|
+
interval: "weekly"
|
|
16
|
+
day: "monday"
|
|
17
|
+
open-pull-requests-limit: 5
|
|
18
|
+
labels:
|
|
19
|
+
- "dependencies"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["**"]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint & Format
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v6.0.2
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v6.2.0
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- uses: astral-sh/setup-uv@v7.5.0
|
|
22
|
+
|
|
23
|
+
- run: uv pip install --system ".[dev]"
|
|
24
|
+
|
|
25
|
+
- run: ruff check .
|
|
26
|
+
|
|
27
|
+
- run: black --check . --target-version py312
|
|
28
|
+
|
|
29
|
+
test:
|
|
30
|
+
name: Tests
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v6.0.2
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v6.2.0
|
|
37
|
+
with:
|
|
38
|
+
python-version: "3.12"
|
|
39
|
+
|
|
40
|
+
- uses: astral-sh/setup-uv@v7.5.0
|
|
41
|
+
|
|
42
|
+
- run: uv pip install --system ".[dev]"
|
|
43
|
+
|
|
44
|
+
- name: Write cookies.json
|
|
45
|
+
if: ${{ env.COOKIES_JSON != '' }}
|
|
46
|
+
run: echo "$COOKIES_JSON" > cookies.json
|
|
47
|
+
env:
|
|
48
|
+
COOKIES_JSON: ${{ secrets.COOKIES_JSON }}
|
|
49
|
+
|
|
50
|
+
- run: pytest
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: ["CI"]
|
|
6
|
+
types: [completed]
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
version-check:
|
|
11
|
+
name: Version Check
|
|
12
|
+
if: github.event.workflow_run.conclusion == 'success'
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
outputs:
|
|
15
|
+
version: ${{ steps.version.outputs.value }}
|
|
16
|
+
is-new: ${{ steps.tag.outputs.is-new }}
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v6.0.2
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
|
|
23
|
+
- name: Read version
|
|
24
|
+
id: version
|
|
25
|
+
run: |
|
|
26
|
+
value=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
|
|
27
|
+
echo "value=$value" >> $GITHUB_OUTPUT
|
|
28
|
+
|
|
29
|
+
- name: Check tag
|
|
30
|
+
id: tag
|
|
31
|
+
run: |
|
|
32
|
+
if git ls-remote --tags origin "refs/tags/v${{ steps.version.outputs.value }}" | grep -q .; then
|
|
33
|
+
echo "is-new=false" >> $GITHUB_OUTPUT
|
|
34
|
+
else
|
|
35
|
+
echo "is-new=true" >> $GITHUB_OUTPUT
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
build:
|
|
39
|
+
name: Build
|
|
40
|
+
needs: version-check
|
|
41
|
+
if: needs.version-check.outputs.is-new == 'true'
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v6.0.2
|
|
46
|
+
|
|
47
|
+
- uses: actions/setup-python@v6.2.0
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.12"
|
|
50
|
+
|
|
51
|
+
- uses: astral-sh/setup-uv@v7.5.0
|
|
52
|
+
|
|
53
|
+
- run: uv build
|
|
54
|
+
|
|
55
|
+
- uses: actions/upload-artifact@v7
|
|
56
|
+
with:
|
|
57
|
+
name: dist
|
|
58
|
+
path: dist/*
|
|
59
|
+
|
|
60
|
+
publish:
|
|
61
|
+
name: Publish to PyPI
|
|
62
|
+
needs: [version-check, build]
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
environment:
|
|
65
|
+
name: pypi
|
|
66
|
+
url: https://pypi.org/project/pyfragment/
|
|
67
|
+
permissions:
|
|
68
|
+
id-token: write
|
|
69
|
+
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/download-artifact@v8.0.1
|
|
72
|
+
with:
|
|
73
|
+
name: dist
|
|
74
|
+
path: dist
|
|
75
|
+
|
|
76
|
+
- uses: pypa/gh-action-pypi-publish@v1.13.0
|
|
77
|
+
|
|
78
|
+
release:
|
|
79
|
+
name: GitHub Release
|
|
80
|
+
needs: [version-check, build]
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
permissions:
|
|
83
|
+
contents: write
|
|
84
|
+
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/checkout@v6.0.2
|
|
87
|
+
with:
|
|
88
|
+
fetch-depth: 0
|
|
89
|
+
|
|
90
|
+
- uses: actions/download-artifact@v8.0.1
|
|
91
|
+
with:
|
|
92
|
+
name: dist
|
|
93
|
+
path: dist
|
|
94
|
+
|
|
95
|
+
- uses: softprops/action-gh-release@v2.6.1
|
|
96
|
+
with:
|
|
97
|
+
tag_name: v${{ needs.version-check.outputs.version }}
|
|
98
|
+
name: v${{ needs.version-check.outputs.version }}
|
|
99
|
+
files: dist/*
|
|
100
|
+
generate_release_notes: true
|
|
101
|
+
make_latest: true
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
.Python
|
|
7
|
+
|
|
8
|
+
# Virtual environments
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
|
|
12
|
+
# IDE
|
|
13
|
+
.idea/
|
|
14
|
+
.vscode/
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
logs/
|
|
18
|
+
*.log
|
|
19
|
+
|
|
20
|
+
# Environment variables
|
|
21
|
+
.env
|
|
22
|
+
|
|
23
|
+
# System files
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
|
|
27
|
+
# Testing & tooling artifacts
|
|
28
|
+
.hypothesis/
|
|
29
|
+
.pytest_cache/
|
|
30
|
+
.mypy_cache/
|
|
31
|
+
.ruff_cache/
|
|
32
|
+
.coverage
|
|
33
|
+
htmlcov/
|
|
34
|
+
demo.run.py
|
|
35
|
+
|
|
36
|
+
# Build & distribution
|
|
37
|
+
dist/
|
|
38
|
+
build/
|
|
39
|
+
*.egg-info/
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to pyfragment are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project uses [Calendar Versioning](https://calver.org/) (`YYYY.MINOR.MICRO`).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [2026.0.1] — 2026-03-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Initial stable release of `pyfragment`
|
|
14
|
+
- `FragmentClient` — async client for the Fragment.com API with context manager support (`async with`)
|
|
15
|
+
- `purchase_premium(username, months)` — purchase Telegram Premium for any user (3, 6, or 12 months)
|
|
16
|
+
- `purchase_stars(username, amount)` — send Telegram Stars to any user (50–1,000,000)
|
|
17
|
+
- `topup_ton(username, amount)` — top up TON Ads balance (1–1,000,000,000 TON)
|
|
18
|
+
- `get_wallet()` — fetch wallet address and balance
|
|
19
|
+
- Support for TON wallet versions `V4R2` and `V5R1`
|
|
20
|
+
- Structured exception hierarchy (`FragmentError`, `ConfigurationError`, `CookieError`, etc.)
|
|
21
|
+
- `py.typed` marker — full PEP 561 typing support for type-checkers
|
|
22
|
+
- `__repr__` on all result types for readable debug output
|
|
23
|
+
|
|
24
|
+
[2026.0.1]: https://github.com/bohd4nx/pyfragment/releases/tag/v2026.0.1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 bohd4nx
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyfragment
|
|
3
|
+
Version: 2026.0.1
|
|
4
|
+
Summary: Python library for the Fragment.com API — purchase Telegram Stars, Premium, and top up TON Ads balance.
|
|
5
|
+
Project-URL: Homepage, https://github.com/bohd4nx/pyfragment
|
|
6
|
+
Project-URL: Repository, https://github.com/bohd4nx/pyfragment
|
|
7
|
+
Project-URL: Issues, https://github.com/bohd4nx/pyfragment/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/bohd4nx/pyfragment/blob/master/CHANGELOG.md
|
|
9
|
+
Author: bohd4nx
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: blockchain,crypto,fragment,premium,stars,telegram,ton
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Framework :: AsyncIO
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Internet
|
|
22
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.12
|
|
26
|
+
Requires-Dist: httpx==0.28.1
|
|
27
|
+
Requires-Dist: tonutils[pytoniq]==2.0.4
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: black; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio==1.3.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest==9.0.2; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<div align="center">
|
|
36
|
+
<img src="fragment.svg" alt="Fragment Logo" width="120" height="120" style="border-radius: 24px;">
|
|
37
|
+
|
|
38
|
+
<h1 style="margin-top: 24px;">Fragment API</h1>
|
|
39
|
+
|
|
40
|
+
<p style="font-size: 18px; margin-bottom: 24px;">
|
|
41
|
+
<b>Python library for the Fragment.com API — purchase Telegram Stars, Premium, and top up TON Ads balance.</b>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
[](https://pypi.org/project/pyfragment/)
|
|
45
|
+
[](https://pypi.org/project/pyfragment/)
|
|
46
|
+
[](https://python.org)
|
|
47
|
+
[](LICENSE)
|
|
48
|
+
[](https://github.com/bohd4nx/pyfragment/stargazers)
|
|
49
|
+
[](https://github.com/bohd4nx/pyfragment/actions)
|
|
50
|
+
|
|
51
|
+
[Report Bug](https://github.com/bohd4nx/pyfragment/issues) · [Request Feature](https://github.com/bohd4nx/pyfragment/issues) · [**Donate TON**](https://app.tonkeeper.com/transfer/UQCppfw5DxWgdVHf3zkmZS8k1mt9oAUYxQLwq2fz3nhO8No5)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
> **Disclaimer:** This project is not affiliated with, endorsed by, or in any way officially connected with [Fragment](https://fragment.com) or [Telegram](https://telegram.org).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ✨ Features
|
|
60
|
+
|
|
61
|
+
- 💰 **TON Advertisement Topups** — Top up Telegram Ads balance (1–1,000,000,000 TON)
|
|
62
|
+
- 👑 **Telegram Premium** — Purchase Premium for any user (3, 6, or 12 months)
|
|
63
|
+
- ⭐ **Telegram Stars Purchases** — Purchase Stars for any Telegram user (50–1,000,000 Stars)
|
|
64
|
+
- 🔐 **Multi-wallet support** — V4R2 and V5R1 wallet contract versions
|
|
65
|
+
- ⚡ **Async-first** — Built on `httpx` and `asyncio`
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 📦 Installation
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install pyfragment
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Requires **Python 3.12+**.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 🚀 Quick Start
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import asyncio
|
|
83
|
+
from pyfragment import FragmentClient
|
|
84
|
+
|
|
85
|
+
async def main():
|
|
86
|
+
async with FragmentClient(
|
|
87
|
+
seed="word1 word2 ... word24",
|
|
88
|
+
api_key="YOUR_TONAPI_KEY",
|
|
89
|
+
cookies={
|
|
90
|
+
"stel_ssid": "...",
|
|
91
|
+
"stel_dt": "...",
|
|
92
|
+
"stel_token": "...",
|
|
93
|
+
"stel_ton_token": "...",
|
|
94
|
+
},
|
|
95
|
+
) as client:
|
|
96
|
+
# Purchase 6 months of Telegram Premium
|
|
97
|
+
result = await client.purchase_premium("@username", months=6)
|
|
98
|
+
print(result.transaction_id)
|
|
99
|
+
|
|
100
|
+
# Purchase 500 Stars
|
|
101
|
+
result = await client.purchase_stars("@username", amount=500)
|
|
102
|
+
print(result.transaction_id)
|
|
103
|
+
|
|
104
|
+
# Top up 10 TON to Ads balance
|
|
105
|
+
result = await client.topup_ton("@username", amount=10)
|
|
106
|
+
print(result.transaction_id)
|
|
107
|
+
|
|
108
|
+
asyncio.run(main())
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
See the [`examples/`](examples/) folder for ready-to-run scripts.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 🔧 Configuration
|
|
116
|
+
|
|
117
|
+
### `FragmentClient` parameters
|
|
118
|
+
|
|
119
|
+
| Parameter | Type | Required | Default | Description |
|
|
120
|
+
| ---------------- | ------------- | -------- | -------- | -------------------------------------------------------- |
|
|
121
|
+
| `seed` | `str` | ✅ | — | 24-word TON wallet mnemonic phrase |
|
|
122
|
+
| `api_key` | `str` | ✅ | — | Tonapi key from [tonconsole.com](https://tonconsole.com) |
|
|
123
|
+
| `cookies` | `dict \| str` | ✅ | — | Fragment session cookies (dict or JSON string) |
|
|
124
|
+
| `wallet_version` | `str` | ❌ | `"V5R1"` | Wallet contract version: `"V4R2"` or `"V5R1"` |
|
|
125
|
+
|
|
126
|
+
### Methods
|
|
127
|
+
|
|
128
|
+
> Usernames can be passed with or without `@`.
|
|
129
|
+
|
|
130
|
+
| Method | Returns | Description | Limits |
|
|
131
|
+
| -------------------------------------------------- | ---------------- | ---------------------------------- | ------------------------- |
|
|
132
|
+
| `purchase_premium(username, months, show_sender=True)` | `PremiumResult` | Purchase Telegram Premium | `months`: 3, 6, or 12 |
|
|
133
|
+
| `purchase_stars(username, amount, show_sender=True)` | `StarsResult` | Purchase Telegram Stars | `amount`: 50–1,000,000 |
|
|
134
|
+
| `topup_ton(username, amount, show_sender=True)` | `AdsTopupResult` | Top up Telegram Ads balance | `amount`: 1–1,000,000,000 |
|
|
135
|
+
| `get_wallet()` | `WalletInfo` | Get wallet address, state, balance | — |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## ⚙️ Getting Required Credentials
|
|
140
|
+
|
|
141
|
+
### 🍪 Fragment.com Cookies
|
|
142
|
+
|
|
143
|
+
**Prerequisites**: Log in to [fragment.com](https://fragment.com), connect your TON wallet.
|
|
144
|
+
|
|
145
|
+
1. Install [Cookie Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)
|
|
146
|
+
2. Open [fragment.com](https://fragment.com) while logged in
|
|
147
|
+
3. Click the extension → **Export** → **Header String**
|
|
148
|
+
4. Extract these four fields:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"stel_ssid": "...",
|
|
153
|
+
"stel_dt": "...",
|
|
154
|
+
"stel_token": "...",
|
|
155
|
+
"stel_ton_token": "..."
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
> ⚠️ Cookies expire. Refresh them if you start getting `FragmentPageError` or auth errors.
|
|
160
|
+
|
|
161
|
+
### 🔑 Tonapi Key
|
|
162
|
+
|
|
163
|
+
1. Go to [tonconsole.com](https://tonconsole.com)
|
|
164
|
+
2. Register and generate a new API key
|
|
165
|
+
3. Pass it as `api_key` to `FragmentClient`
|
|
166
|
+
|
|
167
|
+
### 🌱 Wallet Seed Phrase
|
|
168
|
+
|
|
169
|
+
If you don't have a TON wallet, create one in [Tonkeeper](https://tonkeeper.com).
|
|
170
|
+
Go to **Settings → Backup** → copy the 24 words.
|
|
171
|
+
|
|
172
|
+
> ⚠️ Never share your seed phrase. Store it offline.
|
|
173
|
+
|
|
174
|
+
### 🔐 Wallet Version
|
|
175
|
+
|
|
176
|
+
| Version | Use when |
|
|
177
|
+
| ------- | -------------------------------------------------------------- |
|
|
178
|
+
| `V5R1` | Default — Tonkeeper / MyTonWallet (wallets created after 2024) |
|
|
179
|
+
| `V4R2` | Older Tonkeeper or hardware wallets |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 🗂️ Error Handling
|
|
184
|
+
|
|
185
|
+
All exceptions inherit from `FragmentError` — see [`pyfragment/types/exceptions.py`](pyfragment/types/exceptions.py) for the full list.
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from pyfragment import FragmentClient, UserNotFoundError, ConfigurationError, WalletError
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
result = await client.purchase_stars("@unknown", amount=100)
|
|
192
|
+
except UserNotFoundError:
|
|
193
|
+
print("User not found on Fragment")
|
|
194
|
+
except WalletError as e:
|
|
195
|
+
print(f"Wallet issue: {e}")
|
|
196
|
+
except ConfigurationError as e:
|
|
197
|
+
print(f"Bad params: {e}")
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
<div align="center">
|
|
203
|
+
|
|
204
|
+
### Made with ❤️ by [@bohd4nx](https://t.me/bohd4nx)
|
|
205
|
+
|
|
206
|
+
**Star ⭐ this repo if you found it useful!**
|
|
207
|
+
|
|
208
|
+
</div>
|