TonConnect instance and a connector created with tc.create_connector(SESSION_KEY).
Restoring a Session
restore() resumes a previously saved session from storage and returns True if an active one was found:
restore() first — starting a new connection while one is already active raises WalletAlreadyConnectedError.
Connecting a Wallet
A connection starts with aConnectRequest built by make_connect_request(), which is then passed to connect(). The call opens a bridge connection and returns the standard tc:// universal link that any TonConnect-compatible wallet can open:
network parameter is a guard: if the wallet that approves the request is connected to a different chain, the connection fails with WalletWrongNetworkError (returned as the error from wait_connect()). Pass None to accept any network.
The library returns plain URL strings. Rendering them as a QR code (or as a button in a Telegram bot) is up to your application — any QR library works on the returned string.
Wallet-Specific Links
make_connect_url() builds a link based on a specific wallet’s universal URL, so it opens directly in that wallet app instead of showing a chooser:
Waiting for the Connection
wait_connect() blocks until the wallet approves or rejects the request and returns a (wallet, error) tuple — exactly one of the two is None:
connector.account exposes the wallet’s address, network, public_key, and state_init; connector.app_wallet is the matched wallet descriptor.
If the user never responds, the pending connect times out after connect()’s timeout (default Connector.DEFAULT_CONNECT_TIMEOUT, 15 minutes) and wait_connect() returns (None, RequestTimeoutError). To cancel a pending connect early (for example, when the user closes the dialog), call connector.drop_connect().
Complete flow:
Connecting with TON Proof
A plain connection only tells you which address the wallet claims. TON Proof adds cryptographic proof of ownership: your backend issues a challenge payload, the wallet signs it together with your app domain, and you verify the signature after connecting.nacl.exceptions.BadSignatureError on failure, so wrap them in a single try/except and disconnect the wallet if the proof does not check out. VerifyTonProof(...).verify() performs five cryptographic checks — the full list, and how to verify a proof received from a frontend as a raw dict, is in Backend Verification.
Disconnecting
disconnect() notifies the wallet, removes the session from storage, and closes the bridge connection. It raises WalletNotConnectedError if no wallet is connected:
Importing a Connection
A session established by a JS frontend using TonConnect UI can be taken over by the Python backend — no new connect flow, no second wallet approval. TonConnect UI keeps its session under twolocalStorage keys:
lastEventId is optional in the ActiveConnection model, but it is needed to resume the SSE stream where it left off and avoid replaying old events — merge it into the connection dict before importing. Validate the merged dict into a typed ActiveConnection and reconstruct a connector with tc.from_connection(...), which stores the connection under the given session key and restores the wallet session:
connector.account, send_transaction, sign_data, and disconnect all work as usual.
Exporting a Connection
The inverse operation returns the stored session as anActiveConnection, or None if there is no active connection:
active_connection.dump() — it uses the camelCase aliases of the TonConnect UI storage format (connectEvent, lastEventId, …), not the Python field names.
Connect Wallet Examples
Full source code of the connect flows on GitHub.
import_connection.py
Full import example with real exported storage values.