Why TON Connect wallet connection fails in production
The wallet connection flow looks linear only on a diagram.
In production, TON Connect errors start where a real user enters the picture: an unavailable provider, a different client version, a timeout — and instead of signing the transaction, the person sees a blank screen or an endless loading indicator.
The most common cause is loss of state when returning to the app. The user goes to the wallet, confirms the connection, returns — and the app no longer remembers which session it initiated.
The session ID has been reset, the incoming link is not matched to the original request, and instead of continuing the flow we get another round of connection.
Next is wallet version incompatibility. Different builds return confirmation differently, some methods are simply not supported, and the handler interprets silence as a refusal.
At the transaction confirmation stage this looks like a drop-off: the wallet opened, the person pressed “Confirm,” the app did not wait for a response and reset the session along with the data already entered.
There is also a third layer — wallet session failure on the user’s side: changing devices, multiple installed wallets, following a link from a messenger where the built-in browser cuts off the return to the app.
All these cases look like “the button doesn’t work,” although a specific state transition is broken.
The cost of such a failure is not a minor inconvenience but lost revenue: the person does not complete a payment, an issuance, or a login to the service, and they do not come back a second time.
Below we break down how this is addressed — from a resilient session to a correct rollback when a connection drops.
What stable wallet integration delivers
Wallet connection is the first step where the most users are lost: going to the wallet and back, different wallets with different behavior, a dropped session when the Mini App is minimized.
In a flow without these branches worked out, the share of successful connections stays at around two-thirds, and the rest do not reach the first action.
The integration is built on TON Connect: a single protocol for connecting and signing transactions instead of custom wrappers for each wallet.
We handle the return from the wallet separately — the app restores the session using the saved request ID, so the user lands where they started, not on a blank screen.
What this changes in measurable terms:
- share of successful connections — 93–97% versus 60–70% before the flow was improved;
- time to first action — 15–20 seconds instead of repeated attempts to “connect again”;
- the wallet session survives minimizing the Mini App, switching to the wallet, and changing networks;
- the user returning to the app does not require reconnecting.
The class of failures eliminated here is the most expensive to support: a break on return, a stale request, a repeated signature for an already sent transaction. Wallet session stability closes these branches, and the connection flow stops being a bottleneck in the funnel.
Wallet connection methods: comparison of modes
TON Connect provides a unified wallet connection layer: the app does not receive a private key but works with signed requests.
But comparing integration modes shows that the connection method defines the boundaries of the flow — where the user confirms the operation, how they return to the interface, and what happens if the mini app is already open in the background.
| Option | When it fits | Limitations |
|---|---|---|
| Built-in mini app browser | Wallet connection in a mini app: the user does not leave Telegram, and the signature is confirmed next to the interface | Only the set of wallets that support operation inside a mini app is available |
| External wallet in a separate app | Maximum wallet coverage and confirmation on the user’s device are needed | A return to the app after signing is required; on some platforms the transition remains manual |
| Connection on a website | Desktop and mobile web where Telegram is not part of the flow | Its own wallet selection, its own handling of connection loss and page reopening |
The limitations of a connection method show up not at the moment of connection but on rollback: the user closed the wallet, canceled the signature, or returned in another tab.
That is why in the integration we describe the session state, request retry, and waiting screen in advance — otherwise support gets a stream of “the button didn’t work” requests.
How the integration proceeds: stages of engineering work
Integration starts not with code but with an analysis of how the app already receives the wallet address and the user’s signature. If this path is not described, every new wallet turns into a separate branch of logic, and the next change breaks the previous one. That is why the first two stages are capturing the current state and mapping the connection flows.
- Entry point audit — we analyze where the app initiates the connection, how it stores session state, and what remains of it after a page reload or return from the wallet.
- Connection flow diagram — on the diagram we capture all branches: connection, transaction signing, user refusal, disconnection, re-entry.
- Environment setup — separate configurations for development, the test environment, and production: manifest URL, domains, list of supported wallets.
- Connection implementation — a shared layer for dApp and Telegram Mini App so that state is read the same way and not duplicated in two places.
- Device testing — a run on real phones and desktop browsers with multiple wallets, including signature interruption and re-entry.
- Edge cases — connection loss, stale session, wallet switch; we capture the behavior and clear messages for the user.
- Handover to support — documentation on flows, a list of environments and failure points, access, and the procedure for rolling back to the previous configuration.
Configurations, keys, and documentation after implementation
After launch, the project retains a set of artifacts that the team uses to develop the TON Connect integration without the original author.
Below is exactly what we hand over and in what form, so that environment changes, wallet updates, and incident analysis do not turn into a back-and-forth with questions about “how this was built.”
- Environment configurations — test, pre-production, and production sets of connection parameters, separate manifests for each domain, secrets moved out of the repository into a vault.
- Connection flow diagram — from opening the wallet and requesting a signature to returning to the app, indicating where the transaction is formed and where the response is verified.
- Key rotation policy — frequency of rotation, who initiates it, and how it is verified that active user sessions do not drop off.
- Access policy — roles in the secret vault, the procedure for granting and revoking rights, actions when an employee leaves, and an access log for keys.
- Team guide — scenarios for common cases: connect a new wallet, update the manifest, reproduce a failure in the test environment, distinguish a signature error from a network error.
- Change rollback plan — the previous stable version of the connection, a list of reversible and irreversible changes, and the procedure for confirming rollback.
- Control points — metrics of successful connections and failure logs that reveal degradation before user requests start coming in.
Case study: how successful wallet connections grew
The client came with an already working Telegram mini app: wallet connection via TON Connect had been implemented, transactions went through, but less than half of started flows reached confirmation.
The task was framed as “reduce drop-off,” so we started not with UI changes but with measuring every step — from button press to signature.
Where connections were lost
The losses were distributed differently than expected. About a quarter of users closed the wallet selection window and did not return — switching between apps on the phone itself turned out to be a barrier.
Another portion was lost on the way back: returning from the wallet did not restore the flow state, the person saw a blank screen and thought the connection had not worked.
Retries worked the worst. The button led to the first step, progress was not saved, and each new attempt started from scratch — instead of increasing successful connections, a retry reproduced the same dead end.
What we changed and what happened
We reworked the flow entirely: connection state is saved until the moment of signing, a retry resumes from the last step, and returning from the wallet automatically pulls in the request result.
We separately added distinguishable screen states — waiting, confirmation, error with a reason — so the user does not have to guess what happened.
In follow-up measurements, the share of successful connections grew from 41% to 79% of started flows.
Retries began to produce a result in two out of three cases instead of isolated ones, and the time from start to signature was almost halved — the “closed and re-entered” cycle disappeared.
How does TON Connect differ in a mini app and on a website?
In a Telegram mini app, the connection is initiated by the built-in wallet: the user stays in the same window, and external apps do not open.
On a website, the browser shows the TON Connect window: on mobile, the wallet is selected by QR code with a transition to the app; on desktop, via an extension. This is where the available wallets, the return point, and the state storage method diverge.
| Scenario | Wallet | User return | State |
|---|---|---|---|
| Mini app | built into the client | instant, the window does not close | within the session, no need to restore |
| Website, mobile browser | external via QR code | via a link from the wallet, the tab is restored | in browser storage, checked on load |
| Website, desktop | extension | the tab remains open | same place, separate branch |
User return is the most painful part. In a mini app, confirmation happens inside the client, and the app works in the same context.
On a website, the mobile flow takes the person to the wallet, and a link brings them back: if the state is not restored on opening, they see “not connected” and repeat the login. That is why the address and connection flag are stored in the browser and checked on every load.
The scope of improvements differs by about a factor of two. A mini app needs only one connection branch: signing, sending, disconnecting. A website needs two branches — mobile wallet and desktop extension — plus handling return by link and disconnection when the account changes.
There are more external wallets on a website, each with its own timeouts and way of reporting a network change, so the connection layer is made shared.
Common technical doubts before starting
At the estimation stage, the same set of questions comes up: which networks are supported, whether existing code will have to be rewritten, how to test the integration before deployment, and what will happen to already connected users. Below are brief answers to each point.
Which networks are supported?
The mainnet and testnet are switched by application settings, not by rewriting the logic.
The wallet reports which network the user is connected to, and if there is a mismatch the transaction is not signed — an operation in the production environment will not go through by accident.
Will existing code have to be rewritten?
Wallet connection is a separate layer: it is responsible for signing and sending transactions, while the business logic remains the same. If you already have your own connection mechanism, we keep it and build on top — working modules do not need to be rewritten.
How can everything be tested before deployment?
We run the scenarios on testnet: connection, signature rejection, reconnection, account change, and loss of connection at the moment of sending. We separately test the return from payment — the app must correctly distinguish success, cancellation, and a stuck operation.
What will happen to existing sessions during an update?
The session is stored on the app and wallet side, not inside a specific build, so an update does not force users to reconnect. If the session format changes, we migrate the data so that old connections continue to work.
Let’s discuss the task: what to clarify before work starts
To come back with an estimate of the scope of work rather than general promises, we need input on the project.
TON Connect integration rarely comes down to a single “Connect wallet” button: behind it are signing flows, session lifetime, failure handling, and linking the wallet to an account on your side. The more precise the task statement at the start, the fewer assumptions in the implementation plan.
What we clarify in the first conversation:
- Runtime environment. A web app in a browser, a mini app inside Telegram, or a desktop client — this determines the set of supported wallets and the method of data exchange between windows.
- Use cases. Only sign-in by signature, or also transfers and payments inside the app — each scenario adds its own branch of checks and tests.
- Session model. Connection lifetime, linking the wallet to a profile, re-entry, and access revocation when the account changes.
- Network and confirmations. Whether we work on mainnet or testnet, how many confirmations we wait for, and how we react to a rejected operation.
- What already exists. Current code, server interfaces, user storage schema — this determines whether we write the integration from scratch or embed it into an existing environment.
- Load and access. How many simultaneous connections are expected, and which keys and data remain inside your infrastructure.
- Definition of done. What we consider the result: the wallet connection itself or the full cycle of operations with it.
Based on these answers, we assemble an implementation plan with stages, team composition, and acceptance points. Describe the task — we will come back with an estimate and a work plan.







