TonConnect manager with per-user connectors. All other pages assume this setup.
Installation
Creating the Manifest
tonconnect-manifest.json describes your application to the wallet. When a user connects, the wallet fetches this file to display your app’s name and icon on the confirmation screen. Create it according to the official guidelines and host it at a publicly reachable HTTPS URL:
url, name, and iconUrl are required; termsOfUseUrl and privacyPolicyUrl are optional.
The manifest domain is what the user sees in the wallet and what backend verification checks against: TON Proof and sign-data results carry the app domain, and Backend Verification validates it against your allowlist.
Storage
Session data is persisted through a small key-value interface,StorageProtocol:
typing.Protocol — any object with these three async methods works, no subclassing required. Values are arbitrary JSON-serializable objects (dicts), not pre-encoded strings.
Two implementations ship with the package:
FileStorage(path)— persists sessions to a JSON file. Suitable for single-process apps; sessions survive restarts.MemoryStorage()— keeps sessions in a plain dict. Suitable for tests and short-lived scripts; all sessions are lost on restart.
Custom storage example
Custom storage example
A Redis-backed implementation (the Serialize values yourself if the store only accepts strings — the library passes and expects plain Python objects.
redis part is illustrative — any async key-value store works the same way):Loading Wallet Apps
AppWalletsLoader fetches the wallet catalogue (Tonkeeper, MyTonWallet, etc.) from the TON registry, with a memory cache and an optional local file fallback:
get_wallets() is synchronous and returns list[AppWallet]; get_wallet(app_name) returns a single descriptor or None. Only wallets with an SSE bridge URL are kept — others cannot receive requests from a backend. If the remote source fails and no usable fallback exists, FetchWalletsError is raised.
Initializing TON Connect
TonConnect is the manager that holds shared configuration and creates per-user connectors:
Creating a Connector
Each user session gets its ownConnector with an isolated storage namespace:
create_connector(session_key)is synchronous.session_keyis the per-user identity — any unique string, typically a Telegram user id (str(user_id)).await connector.restore()resumes a previously saved session from storage; it returnsTrueif an active connection was found. Call it before starting a new connection flow.tc.connectorsis a read-only dict of active connectors keyed by session key.- On application shutdown, call
await tc.close_all()to close all bridge connections.
Examples
Full runnable scripts: connect, transactions, sign data, and verification.