Skip to main content

Python toolkit for reading, decoding, normalizing, and locally caching TON blockchain data.

Project description

tonflow

CI codecov PyPI Python License: MIT

Python toolkit for reading, decoding, normalizing, and locally caching TON blockchain data.

tonflow is a lightweight MIT-licensed library. It does not run a hosted indexer and does not store blockchain data on your behalf — any cache lives on your own machine or infrastructure.

Install

pip install tonflow

Requires Python 3.12+.

Quickstart

import asyncio
from tonflow import TonClient

async def main() -> None:
    async with TonClient(endpoint="https://tonapi.io") as client:
        txs = await client.get_transactions("EQ...", limit=10)
        for tx in txs:
            print(tx.hash, tx.logical_time, tx.status)

asyncio.run(main())

Recipes

Get Jetton transfers

transfers = await client.get_jetton_transfers(
    "EQ...",
    limit=20,
    decimals=6,
    symbol="USDT",
)
for t in transfers:
    print(t.sender, "→", t.recipient, t.amount, t.symbol)

Stream new transactions in real time

from tonflow import watch_address

async for tx in watch_address(client, "EQ...", interval_seconds=5):
    print("new tx:", tx.hash, tx.logical_time)

watch_address runs indefinitely. To stop it after a fixed duration, wrap it with asyncio.timeout (Python 3.11+):

import asyncio
from tonflow import TonClient, watch_address

async def main() -> None:
    async with TonClient(endpoint="https://tonapi.io") as client:
        async with asyncio.timeout(60):  # stop after 60 seconds
            async for tx in watch_address(client, "EQ..."):
                print(tx.hash)

Cache responses locally (avoid hammering public nodes)

from tonflow import SQLiteCache, TonClient

client = TonClient(
    endpoint="https://tonapi.io",
    cache=SQLiteCache(".tonflow/cache.sqlite3"),
    cache_ttl_seconds=60,
)

Export to CSV or JSON

from tonflow import jetton_transfers_to_csv, transactions_to_json

json_str = transactions_to_json(txs, indent=2)
csv_str  = jetton_transfers_to_csv(transfers)

with open("transfers.csv", "w") as f:
    f.write(csv_str)

Validate a TON address

from tonflow import validate_address, is_user_friendly_address, is_raw_address

validate_address("EQ...")        # raises ValueError if invalid
is_user_friendly_address("EQ...") # True / False
is_raw_address("0:abcd...")        # True / False

API reference

TonClient

TonClient(
    endpoint: str,
    api_key: str | None = None,
    timeout: float = 10.0,
    cache: JSONCache | None = None,
    cache_ttl_seconds: float | None = 30.0,
)
Method Description
get_transactions(address, limit, before_lt) Fetch and normalize account transactions
get_jetton_transfers(address, limit, before_lt, decimals, jetton_minter, symbol) Fetch transactions and return only Jetton transfer events
aclose() Close the underlying HTTP client

Use as an async context manager (async with) for automatic cleanup.

watch_address

watch_address(
    client: TonClient,
    address: str,
    interval_seconds: float = 5.0,
    lookback: int = 10,
) -> AsyncIterator[Transaction]

Polls every interval_seconds. Seeds a baseline on the first call so existing transactions are not replayed. Yields new transactions in ascending logical-time order.

Note: watch_address runs indefinitely. Use asyncio.timeout() or task cancellation to stop it.

Models

Model Key fields
Transaction hash, account, logical_time, timestamp, status, in_message, out_messages, total_fees
Message source, destination, direction, value, body, op_code
JettonTransfer transaction_hash, sender, recipient, amount, raw_amount, decimals, symbol, jetton_wallet, jetton_minter, comment

Cache backends

Class Storage Best for
InMemoryCache In-process dict Tests, short-lived scripts
SQLiteCache(path) SQLite file on disk Local scripts, small services

Both implement the JSONCache protocol — you can write your own backend (e.g. Redis) by implementing get, set, and clear.

Export helpers

Function Output
transactions_to_json(txs, indent=None) JSON string
transactions_to_csv(txs) CSV string
jetton_transfers_to_json(transfers, indent=None) JSON string
jetton_transfers_to_csv(transfers) CSV string

Decimal amounts are serialized as strings in both formats to preserve precision.

Address helpers

Function Description
normalize_address(addr) Strip whitespace, raise on empty
is_user_friendly_address(addr) Validate EQ/UQ/kQ/0Q 48-char format
is_raw_address(addr) Validate workchain:64hexchars format
validate_address(addr) Accept either format, raise ValueError on invalid

Exceptions

Exception Raised when
TonflowAPIError HTTP error from upstream TON API
TonflowDecodeError API response cannot be parsed into expected models

Examples

See the examples/ directory:

Development

git clone https://github.com/kakharov/tonflow
cd tonflow
py -3.12 -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
pytest

Lint and type check:

ruff check .
ruff format .
mypy src/

Roadmap

0.1.0 — current

  • TonClient with get_transactions() and get_jetton_transfers()
  • TEP-74 Jetton transfer decoder
  • SQLiteCache and InMemoryCache with TTL
  • watch_address() polling stream
  • Address validation (user-friendly and raw formats)
  • JSON and CSV export helpers

0.2.0 — planned

TonCenter adapter

TON ecosystem has multiple API providers with different trade-offs:

Provider Cost Reliability Notes
TonAPI Paid High More endpoints, better rate limits
TonCenter Free Medium Can drop transactions under load
Lite Server Free Highest Direct node connection, complex setup

0.2.0 adds a pluggable provider system so you can switch between TonAPI and TonCenter without changing your code.

send_and_confirm()

TON is fully asynchronous — sending a transaction does not mean it was executed. Unlike Ethereum, there is no immediate transaction hash to track. Transactions can silently disappear from the mempool due to:

  • valid_until TTL expiry (transaction not included in a block in time)
  • TonCenter queue drops under high load
  • seqno race conditions when sending in parallel

send_and_confirm() solves this by:

  1. Sending the transaction via any configured provider
  2. Polling every few seconds until the transaction appears on-chain
  3. Automatically retrying with a fresh seqno if valid_until has passed and the transaction is gone
  4. Returning only after the transaction is confirmed in a block
result = await client.send_and_confirm(
    wallet=wallet,
    messages=[...],
    timeout=60,
)
print(result.hash, result.logical_time)

Full 0.2.0 scope

  • TonCenter adapter (pluggable provider interface)
  • send_and_confirm() with polling, TTL tracking and automatic retry
  • Websocket stream support (TonAPI / TonCenter)
  • Jetton burn and mint event decoding
  • Redis cache adapter

0.3.0 — planned

  • NFT transfer event decoding
  • CLI: tonflow scan <address>
  • Postgres export helper
  • Backfill utility for historical data

License

MIT

Project details


Download files

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

Source Distribution

tonflow-0.1.0.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

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

tonflow-0.1.0-py3-none-any.whl (16.8 kB view details)

Uploaded Python 3

File details

Details for the file tonflow-0.1.0.tar.gz.

File metadata

  • Download URL: tonflow-0.1.0.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tonflow-0.1.0.tar.gz
Algorithm Hash digest
SHA256 92ee65725119b71c344e7a3476596ca89fb605a91fdc253fd1ee86e7b9b3a93d
MD5 79ede4a125f4971ea1aa5d942bec9174
BLAKE2b-256 340cc41bbf16d5ab49e8cce60784b0fe909ce6281d44ee538ae1b1e532e8a405

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonflow-0.1.0.tar.gz:

Publisher: publish.yml on kakharov/tonflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tonflow-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: tonflow-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tonflow-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 368734b130ac5616e15fdfbece01a2d058ad05cbb37df25de48544d9b7b7f634
MD5 7adaa87bac8b3752a0f0c9511f1eddf4
BLAKE2b-256 dd0210cfa8d8d4713ee59ebbee5bfd00b36faa866e1b5e0ec8000c00527433d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonflow-0.1.0-py3-none-any.whl:

Publisher: publish.yml on kakharov/tonflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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