Skip to main content

mystars-faas

PyPI Python license

Official Python SDK for the MyStars FaaS API — buy Telegram Stars & Premium for any @username, paid in TON or USDT (TON).

Sync + async clients, exact-Decimal money, typed errors, automatic retries + idempotency, webhook verification, a retail-markup calculator, and dependency-free on-chain payload builders.

Compatible with FaaS API v1.11.0. Requires Python ≥ 3.9. Only runtime dependency: httpx.

📖 Full interactive API reference: mystars.tg/docs. SDK method/function reference: api-python.md. Changelog: CHANGELOG.md.

Install

pip install mystars-faas

Keys are issued in the MyStars Telegram bot — open @my_stars_tg_bot, tap API access, copy your X-Api-Key.

Runnable examples live in examples/ (quickstart + webhook receiver).

Quick start

The client reads your key from the environment. Set it before running — export MYSTARS_API_KEY=faas_.... If you keep keys in a .env file, load it yourself (e.g. with python-dotenvload_dotenv()); it is not a dependency of this SDK, so os.environ["MYSTARS_API_KEY"] alone won't read a .env.

import os
from mystars_faas import MyStarsClient

client = MyStarsClient.production(os.environ["MYSTARS_API_KEY"])

quote = client.get_pricing(type="stars", quantity=100, payment_currency="ton")
print("pay", quote.amount, quote.currency)

check = client.check_recipient("durov", type="stars")
if not check.eligible:
    raise SystemExit(check.telegram_message)
# check.indeterminate is True when the check couldn't decide and failed open, so
# `eligible` is a default, not a measurement. Treat it as "unknown", never as "yes":
# ordering is still safe (the order re-checks authoritatively), but don't tell the
# buyer the recipient is confirmed.

order = client.create_order(            # an Idempotency-Key is generated + reused on retry
    type="stars", recipient="durov", quantity=100,
    callback_url="https://your-app.example.com/webhooks/mystars",
)
# Pay order.payment.amount to order.payment.pay_to_address with the comment order.payment.memo.
print(order.payment)

final = client.wait_for_order(order.order_id, on_update=lambda o: print("status:", o.status))
print("done:", final.status, final.purchase_tx)

Async

from mystars_faas import AsyncMyStarsClient

async with AsyncMyStarsClient.production(key) as client:
    quote = await client.get_pricing(type="premium", months=3, payment_currency="usdt_ton")
    async for order in client.aiter_orders(status="delivered"):
        ...

Webhooks

from mystars_faas import WebhookVerifier

verifier = WebhookVerifier(WEBHOOK_SECRET)
event = verifier.verify(raw_body, request.headers["X-Faas-Signature"])  # raises on bad signature
# event.order_id, event.status — dedup on order_id (delivery is at-least-once)

Handles the 24h "current,previous" rotation header automatically. FastAPI / Flask route factories live in mystars_faas.integrations.fastapi / .flask (install mystars-faas[fastapi] / [flask]).

Your own retail markup

from mystars_faas import apply_retail_markup

quote = client.get_pricing(type="stars", quantity=100, payment_currency="usdt_ton")
retail = apply_retail_markup(quote, margin_pct=15, pass_through_processing_fee=True)
print(retail.total)   # decimal string — exact (computed in Decimal), two-stage cent-ceil
print(retail.profit)  # decimal string — your gross margin

All RetailQuote money fields (total, profit, subtotal, …) are returned as decimal strings, not Decimal. For a usdt_ton quote, the markup needs the fee breakdown — if the quote came back with fee=None (a cold-FX /v1/pricing row), apply_retail_markup raises MyStarsValidationError; re-quote get_pricing(...) to obtain the fee block first.

Pay an order (non-custodial)

order.payment (a PaymentInstruction) is on the create_order result (CreateOrderResult). An Order from get_order / wait_for_order has no .payment — read amount_ton, payment_tx, and purchase_tx there instead.

from mystars_faas import build_payment_request

req = build_payment_request(order.payment)   # order = the create_order(...) result
print(req.ton_deeplink)        # ton://transfer/... (TON only)
print(req.ton_connect[0])      # ton_connect is a list[TonConnectMessage] (one entry for TON)

Holds no keys. Errors are typed subclasses of MyStarsAPIError (RecipientIneligibleError, RateLimitedError, …); the client retries transient failures (network, timeout, 502/503/504, 500, general 429 — honoring Retry-After, including the HTTP-date form) automatically and idempotency-safely. A response body larger than 4 MB is rejected (response_too_large) instead of being buffered whole.

Errors

Class HTTP TS-SDK alias
MyStarsValidationError — (client-side)
BadRequestError 400
AuthenticationError 401 UnauthorizedError
PermissionDeniedError 403 ForbiddenError
NotFoundError 404
ConflictError / IdempotencyConflictError / OrderNotCancellableError 409
RecipientIneligibleError 422
RateLimitedError 429
InternalServerError / ServiceUnavailableError 500 / 503
MyStarsTransportError / TimeoutError_ — (no response)

UnauthorizedError and ForbiddenError are exported aliases of AuthenticationError / PermissionDeniedError so code written against the TypeScript SDK's names catches the same error.

CLI

mystars-faas --api-key "$MYSTARS_API_KEY" pricing --type stars --quantity 100 --currency ton
mystars-faas orders-create --type stars --recipient durov --quantity 100 --pay

# Verify a webhook offline. Prefer the env var — a --secret on argv is visible in `ps`.
export MYSTARS_WEBHOOK_SECRET="…"
mystars-faas webhook-verify --body "$RAW_BODY" --signature "$X_FAAS_SIGNATURE"

webhook-verify reads the secret from MYSTARS_WEBHOOK_SECRET (preferred) or --secret; the env var wins when both are set, because a command-line --secret leaks via the process list and shell history.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mystars_faas-0.1.7.tar.gz (39.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mystars_faas-0.1.7-py3-none-any.whl (48.6 kB view details)

Uploaded Python 3

File details

Details for the file mystars_faas-0.1.7.tar.gz.

File metadata

  • Download URL: mystars_faas-0.1.7.tar.gz
  • Upload date:
  • Size: 39.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for mystars_faas-0.1.7.tar.gz
Algorithm Hash digest
SHA256 cfcbd4e0dffc382c8bcd7f46f1a5967863ff48a359bf700305e2b39c1dec19c5
MD5 bf964be5d89df9843dba4aebd055a226
BLAKE2b-256 f92cdbd2fcb3758315035feaaaafd338fd5f2879ee81e5f53b109cce40f8ef3a

See more details on using hashes here.

File details

Details for the file mystars_faas-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: mystars_faas-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 48.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for mystars_faas-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 ff3fec28b32e459810b5c9fadc9cd7b3fed9ef23d987c73bf3ab5c86f82b6e01
MD5 48bb128b19a90569a38aa5fb88d7d78b
BLAKE2b-256 04feca42e44c486744d5471faa004055247efd9a327ddd7006402dec281145ee

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page