-
Notifications
You must be signed in to change notification settings - Fork 57
feat(sub-second): add how to adopt sub-second finality page #1987
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aigerimu
wants to merge
16
commits into
main
Choose a base branch
from
subsecond-page
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+283
−1
Open
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
d9429f9
sub-second-pr
aigerimu b794928
ci
aigerimu de21fed
ci
aigerimu dc35f33
ai
aigerimu 072f456
ms-for-milliseconds
aigerimu 3e498cb
restructured
aigerimu 60bf0aa
clarifying-which-example
aigerimu ebf7ef5
Apply a batch of edited suggestions given by AI
novusnota f875249
fix
novusnota c703c17
fmt
aigerimu 52c07f1
Update ecosystem/subsecond.mdx
aigerimu 9661711
Update ecosystem/subsecond.mdx
aigerimu ad79d56
Merge branch 'main' into subsecond-page
aigerimu 454b445
Apply the second batch of edited suggestions given by AI
aigerimu 720a52d
renaming-behavior
aigerimu a629dac
tag new
novusnota File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -122,6 +122,7 @@ | |
| "ecosystem/api/price" | ||
| ] | ||
| }, | ||
| "ecosystem/subsecond", | ||
| "ecosystem/status", | ||
| "ecosystem/analytics", | ||
| { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,282 @@ | ||
| --- | ||
| title: "How to adopt sub-second finality" | ||
| sidebarTitle: "Sub-second finality" | ||
| tag: "new" | ||
| --- | ||
|
|
||
| import { Aside } from '/snippets/aside.jsx'; | ||
|
|
||
| Sub-second finality is an upgrade in which transactions are processed and finalized in under 1 second. It combines faster block production with low-latency APIs. _The goal of this upgrade_ is to enable end-to-end interactions to complete in under 1 second. | ||
|
|
||
| However, upgrading the blockchain does not automatically improve application behavior. To expose this performance in real time, ecosystem projects must adapt their apps to surface transaction updates promptly. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Current status | ||
|
|
||
| The testnet has had the sub-second upgrade since January 23, 2026. Mainnet validators received it on February 12, 2026, but it remains disabled until testnet validation is complete. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <Aside type="note">The mainnet activation date is still unannounced.</Aside> | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| | Network | Block interval | Blocks per second (BPS) | Pending lag | Finalization lag | | ||
| | --------------- | -------------- | ----------------------- | ----------- | ---------------- | | ||
| | Current mainnet | \~2.5s | \~0.4 BPS | \~30–100ms | \~10s | | ||
| | Current testnet | \~450ms | \~2.2 BPS | \~30–100ms | \~1-2s | | ||
| | Target mainnet | 200–400ms | \~2.5–5 BPS | \~30–100ms | \~1s | | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Testnet operates close to the target speed (200–400ms block finality) and is the primary environment for testing. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Example of sub-second UI: | ||
|
|
||
| <video | ||
| autoPlay | ||
| muted | ||
| loop | ||
| src="/resources/videos/subsecond-example.mov" | ||
| alt="Sub-second UI example" | ||
| /> | ||
|
|
||
| _[The video source](https://t.me/anatolii_makosov/110)._ | ||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| MyTonWallet and [tonscan.org](https://tonscan.org) use Streaming API v2 on both mainnet and testnet to deliver transaction status updates with low latency, even though the sub-second upgrade is not yet enabled on mainnet. | ||
|
|
||
| ## What projects need to do | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Update wallets and apps for sub-second finality | ||
|
|
||
| A faster chain alone does not reduce end-to-end latency if the application continues to use HTTP polling. In this case, transaction status updates can still arrive 10 seconds or more after inclusion. To support sub-second latency, deliver transaction updates through streaming APIs instead of polling. | ||
|
|
||
| #### Requirements | ||
|
|
||
| 1. Switch to [TON Center Streaming API v2](#ton-center-streaming-api-v2) or TonAPI Streaming API to receive transaction status updates with 30–100ms latency. | ||
| 1. Handle all four transaction statuses: `"pending"`, `"confirmed"`, `"finalized"`, `"trace_invalidated"`. | ||
|
|
||
| If Streaming API cannot be used, reduce polling intervals and adjust assumptions about transaction timing. Interfaces should be designed to expect results in under 1 second. | ||
|
|
||
| ### Prepare self-hosted nodes, liteservers, and TON Center instances | ||
|
|
||
| #### Requirements | ||
|
|
||
| 1. Update all self-hosted components to the versions that include Catchain 2.0 support: | ||
|
|
||
| - TON node and liteserver – update to the latest release before mainnet activation. | ||
| - Self-hosted TON Center – update to the version with Streaming API v2 support. | ||
|
|
||
| 1. After updating, connect each component to testnet and verify that it operates correctly under the higher block rate. Do not wait for mainnet activation; issues identified late are harder to resolve. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Prepare indexers for higher block rates | ||
|
|
||
| Indexers must process up to approximately 5 blocks per second without accumulating lag, compared to a baseline of about 0.5 blocks per second. | ||
|
|
||
| #### Requirements | ||
|
|
||
| 1. Connect the indexer to testnet. | ||
|
|
||
| 1. Run for 30+ minutes. | ||
|
|
||
| 1. Measure lag continuously. | ||
|
|
||
| - If lag increases, identify the bottleneck, including database writes, network, parsing. | ||
| - Resolve bottlenecks before mainnet activation. | ||
|
|
||
| 1. Generate the typical mainnet load profile on testnet, following the guidance in [Expected user experience](#expected-user-experience) and [Test on testnet](#test-on-testnet). | ||
|
|
||
| ## Expected user experience | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Behavior without streaming APIs | ||
|
|
||
| Even if the blockchain produces blocks up to 10x faster, apps that do not use streaming APIs still: | ||
|
|
||
| - Poll HTTP endpoints at fixed intervals. | ||
| - Wait for full block finalization before updating the UI. | ||
| - Show delays of 10+ seconds to users. | ||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| A typical sequence for polling-based integrations: | ||
|
|
||
| 1. 0s – user clicks "Send"; | ||
| 1. \~0.4s – transaction included in a shard block; | ||
| 1. \~0.8s – shard block committed to masterchain; | ||
| 1. \~10s – UI updates on the next polling request. | ||
|
|
||
| User perception: "The blockchain is fast, but the transfer still takes 10 seconds." | ||
|
|
||
| ### Behavior with streaming APIs | ||
|
|
||
| 1. 0s – user clicks "Send"; | ||
| 1. \~0.1s – `"pending"` status with expected outcome is displayed; | ||
| 1. \~0.4s – transaction included in a shard block and `"confirmed"` status is displayed; | ||
| 1. \~0.8s – shard block committed to masterchain and `"finalized"` status is displayed. | ||
|
|
||
| Key question: | ||
|
|
||
| Does the UI update fast enough to reflect transactions that complete in under 1 second? If not, users will not experience any improvement despite the chain upgrade. | ||
|
|
||
| ### Why this matters | ||
|
|
||
| The sub-second finality rollout requires coordinated changes across the ecosystem: | ||
|
|
||
| - TON Core delivers faster block production and low-latency APIs. | ||
| - Ecosystem projects must adapt indexers and UI layers to surface this speed. | ||
|
|
||
| If apps do not adapt, the upgrade appears ineffective, even when the underlying system operates correctly. Projects that are ready before the mainnet rollout will demonstrate the intended behavior and user experience. | ||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ## How to integrate | ||
|
|
||
| ### Recommended stack | ||
|
|
||
| For projects building on TON: | ||
|
|
||
| - Data layer: TON Center Streaming API v2 with 30–100ms latency. | ||
| - SDK: [AppKit](/ecosystem/appkit/overview) for balances, tokens, NFTs, and contract interactions. | ||
| - Finality: wait `"finalized"` status for critical flows. | ||
|
|
||
| For API reference, see the [API overview](/ecosystem/api/overview). | ||
|
|
||
| ### Liteserver connection | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Public liteservers are available for both mainnet and testnet. Use global config files to discover and connect to them: | ||
|
|
||
| - Mainnet: [`ton.org/global.config.json`](https://ton.org/global.config.json) | ||
| - Testnet: [`ton.org/testnet-global.config.json`](https://ton.org/testnet-global.config.json) | ||
|
|
||
| <Aside | ||
| type="caution" | ||
| > | ||
| Public liteservers are suitable for testing only. Use private liteservers in production. | ||
| </Aside> | ||
|
|
||
| ### Self-hosted liteserver updates | ||
|
|
||
| If a liteserver node is self-hosted, ensure it is updated before mainnet rollout. | ||
|
|
||
| #### Requirements | ||
|
|
||
| Confirm that the node version supports the new consensus. | ||
|
|
||
| ### TON Center Streaming API v2 | ||
|
|
||
| [TON Center Streaming API v2](https://gist.github.com/dungeon-master-666/98db8d73e9cd9a1b7802bc06ded5b155) provides: | ||
|
|
||
| - Push-based delivery of transaction status updates. | ||
| - Four statuses: `"pending"`, `"confirmed"`, `"finalized"`, `"trace_invalidated"`. | ||
| - Latency: 30–100ms from chain event to the client. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| #### API token | ||
|
|
||
| - For testing purposes, any valid token for TON Center allows for 2 concurrent streaming connections. | ||
| - For production usage, higher connection limits require a paid plan. | ||
|
|
||
| #### Endpoints | ||
|
|
||
| SSE and WebSocket are available. Choose based on the stack: | ||
|
|
||
| - SSE – browser-friendly, server-to-client only (unidirectional). | ||
| - WebSocket – bidirectional, allows dynamic subscribe and unsubscribe after connection. | ||
|
|
||
| | Protocol | Testnet URL | Mainnet URL | | ||
| | --------- | ---------------------------------------------------- | -------------------------------------------- | | ||
| | SSE | `https://testnet.toncenter.com/api/streaming/v2/sse` | `https://toncenter.com/api/streaming/v2/sse` | | ||
| | WebSocket | `wss://testnet.toncenter.com/api/streaming/v2/ws` | `wss://toncenter.com/api/streaming/v2/ws` | | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| <Aside | ||
| type="caution" | ||
| title={"SSE known limitations"} | ||
| > | ||
| 1. Rate limit on reconnect (429 error). | ||
|
|
||
| If a client reconnects immediately after a disconnect, the previous connection may still be open for \~1 minute. The reconnect attempt receives a 429 error. Use exponential backoff or an enterprise API key. | ||
|
|
||
| 1. POST-only subscription. | ||
|
|
||
| Despite SSE typically using `GET`, this endpoint requires a `POST` with the subscription JSON in the request body. `GET` is not supported yet. | ||
|
|
||
| 1. No invalidation signal for `account_state_change` / `jettons_change`. | ||
|
|
||
| If a `confirmed` account state or jetton balance update is later rolled back, no `"trace_invalidated"` notification is sent for these event types. Teams using `account_state_change` or `jettons_change` at `"confirmed"` finality should be aware of this gap and consider waiting for `"finalized"` for balance-critical flows. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| </Aside> | ||
|
|
||
| #### Transaction status flow to implement | ||
|
|
||
| 1. Initiate the transaction after the user's request. | ||
| 1. Subscribe to the sender or recipient address through the Streaming API before or immediately after sending. | ||
|
|
||
| - On `pending`, display a processing indicator. | ||
| - On `confirmed`, optionally display optimistic success. | ||
| - On `finalized`, display confirmed success and update state. | ||
| - On `trace_invalidated`, discard a cached trace and recheck the status manually. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| #### Configure `min_finality` | ||
|
|
||
| The `min_finality` parameter controls the earliest status delivered. The default value is `"finalized"`. If the parameter is omitted, only `"finalized"` events are delivered; `"pending"` and `"confirmed"` updates are not sent. | ||
|
|
||
| | Use case | `min_finality` value | | ||
| | ------------------------------ | --------------------------------------------- | | ||
| | Send flow (real-time feedback) | `"pending"` to receive four status updates. | | ||
| | History and balance display | `"finalized"` to work only with settled data. | | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Example subscription (send flow): | ||
|
|
||
| ```json | ||
| { | ||
| "accounts": ["<ADDRESS>"], | ||
| "min_finality": "pending" | ||
| } | ||
| ``` | ||
|
|
||
| #### WebSocket keepalive | ||
|
|
||
| - Send a `ping` every 15 seconds to keep the connection alive. | ||
| - SSE connections receive automatic server-side keepalive (`: keepalive`) every 15 seconds; no client action required. | ||
|
|
||
| ### AppKit for app developers | ||
|
|
||
| For frontend applications, not a raw indexer, [AppKit](/ecosystem/appkit/overview) provides ready-to-use components. It handles out of the box: | ||
|
|
||
| - TON balance for any address; | ||
| - Jetton balances and metadata; | ||
| - NFT holdings; | ||
| - Contract state reads; | ||
| - Transaction sending, including jetton transfers. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| <Aside type="note"> | ||
| AppKit and [WalletKit](/ecosystem/walletkit/overview) do not yet support Streaming API v2. Projects using these SDKs should follow this guide for streaming integration until native support is available. | ||
| </Aside> | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Test on testnet | ||
|
|
||
| Testnet runs at sub-second speed (200–400ms block finality). Run tests here before enabling sub-second changes on mainnet. | ||
|
|
||
| ### Testnet endpoints | ||
|
|
||
| Use [full list](/ecosystem/api/overview) of public testnet endpoints, including TON Center v2, TON Center v3, TonAPI. | ||
|
|
||
| ### How to get test tokens | ||
|
|
||
| - For the standard faucet, up to 2 TON per hour, [use Telegram Testgiver TON bot](/ecosystem/wallet-apps/get-coins#how-to-get-coins-on-testnet). | ||
| - For larger allocations up to 5,000 TON, [use the request form](/ecosystem/wallet-apps/get-coins#use-request-form). | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### What to test | ||
|
|
||
| To ensure correct UX and wallet behavior, perform the following tests. | ||
|
|
||
| #### For indexer teams | ||
|
|
||
| 1. Connect indexer to testnet. | ||
| 1. Run for 30+ minutes under normal conditions. | ||
| 1. Measure indexer lag as the time between block production and indexer processing. | ||
| 1. Ensure lag remains below 500ms and no backlog accumulates. | ||
|
|
||
| #### For UX and app teams | ||
|
|
||
| 1. Connect to testnet endpoints. | ||
| 1. Initiate a TON transfer. | ||
| 1. Observe three statuses in sequence: `"pending"` → `"confirmed"` → `"finalized"`. | ||
| 1. Measure time from transaction send to `"finalized"`. It should be under 1 second on testnet. | ||
| 1. Test `"trace_invalidated"` path: intentionally send a malformed transaction and confirm that UI handles it correctly. | ||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #### For wallet teams | ||
|
|
||
| 1. Verify balance updates reflect within 1 second of `"finalized"` status. | ||
| 1. Verify transaction history updates in real time. | ||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
aigerimu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ## Get support | ||
|
|
||
| Use the [sub-second finality support chat](https://t.me/subsecond_upgrade) for questions about this upgrade. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1194,7 +1194,6 @@ | |
| !Mr | ||
| !MR | ||
| !mR | ||
| !ms | ||
| !Ms | ||
| !MS | ||
| !mS | ||
|
|
||
Binary file not shown.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.