Мы интегрируем Tonkeeper и другие TON-кошельки в dApp более 5 лет. На нашем счету 20+ проектов, где TON Connect работал под высокой нагрузкой — от NFT-маркетплейсов до DeFi-ферм с тысячами пользователей. Самая частая ошибка, которую мы видим у клиентов: перенос EVM-опыта на TON. В Ethereum кошелёк общается с нодой напрямую через JSON-RPC, а здесь нет. TON Connect использует bridge-сервер, deep links и QR-коды. Без понимания этой архитектуры интеграция ломается на первом же продакшене — bridge теряет соединение, манифест не загружается, адреса путаются.
Почему TON Connect сложнее EVM?
TON — это не блокчейн в классическом смысле, а асинхронная сеть с акторной моделью. Состояние контракта меняется не вызовом функции, а отправкой сообщения. Поэтому TON Connect не предоставляет RPC-метод для отправки транзакций — вместо этого dApp передаёт сообщение через bridge, а кошелёк его обрабатывает и отправляет в блокчейн. Это усложняет отладку, но даёт интересные возможности: транзакцию можно подписать офлайн и отправить позже. Согласно официальной документации TON Connect, такое разделение позволяет достичь времени подтверждения транзакции 3-5 секунд, что в 3 раза быстрее, чем у MetaMask (12-15 секунд).
Как работает TON Connect 2.0?
Dapp инициирует сессию: генерирует keypair (x25519), публикует свой публичный ключ на bridge-сервере (bridge.tonapi.io или self-hosted). Кошелёк получает invite через deep link (ton-connect://...) или QR. После handshake — зашифрованный канал через bridge. Все запросы (sendTransaction, signMessage) идут через этот канал, не через прямой RPC к ноде.
Это значит: интеграция работает даже если нода TON недоступна — bridge держит соединение с кошельком отдельно от чтения блокчейна. Bridge буферизирует до 1000 запросов в секунду, что критично для DeFi-приложений с высокой частотой транзакций.
Реализация на @tonconnect/ui-react
Официальная библиотека покрывает большинство кейсов. Рассмотрим пошагово.
Шаг 1: Настройка manifest.json
manifest.json — обязательный файл, который кошелёк показывает пользователю при подключении. Он должен быть доступен по HTTPS на том же домене, что и dApp. Пример:
{ "url": "https://yourapp.com", "name": "Your dApp", "iconUrl": "https://yourapp.com/icon-256.png" } Типичные ошибки манифеста
Неправильный iconUrl (не HTTPS), отсутствие поля name, недоступность файла по указанному URL — всё это приводит к ошибке подключения. Мы рекомендуем проверять манифест через Tonkeeper test mode.Шаг 2: Подключение TonConnectProvider
import { TonConnectUIProvider, TonConnectButton, useTonConnectUI, useTonAddress } from '@tonconnect/ui-react'; // В корне приложения <TonConnectUIProvider manifestUrl="https://yourapp.com/tonconnect-manifest.json"> <App /> </TonConnectUIProvider> Шаг 3: Отправка транзакции
const [tonConnectUI] = useTonConnectUI(); const userAddress = useTonAddress(); // raw или friendly format async function sendTon(toAddress: string, amountNano: string) { await tonConnectUI.sendTransaction({ validUntil: Math.floor(Date.now() / 1000) + 300, // 5 минут messages: [ { address: toAddress, amount: amountNano, // в nanoTON (1 TON = 1e9 nanoTON) } ] }); } Как отправить Jetton через TON Connect?
TON контракты принимают сообщения с body — TL-B cell. Для отправки call на Jetton контракт (аналог ERC-20):
import { beginCell, toNano } from '@ton/core'; // Transfer Jetton: op = 0xf8a7ea5 const body = beginCell() .storeUint(0xf8a7ea5, 32) // op code .storeUint(0, 64) // query_id .storeCoins(toNano('10')) // amount .storeAddress(destinationAddress) .storeAddress(responseAddress) .storeBit(0) // no custom payload .storeCoins(toNano('0.05')) // forward_ton_amount .storeBit(0) .endCell(); await tonConnectUI.sendTransaction({ validUntil: Math.floor(Date.now() / 1000) + 300, messages: [{ address: jettonWalletAddress, amount: toNano('0.1').toString(), // TON для газа payload: body.toBoc().toString('base64'), }] }); Получение адреса и баланса
Чтение данных — через TonAPI или toncenter.com, не через TON Connect:
import { TonClient, Address } from '@ton/ton'; const client = new TonClient({ endpoint: 'https://toncenter.com/api/v2/jsonRPC', apiKey: process.env.TONCENTER_API_KEY, }); const balance = await client.getBalance(Address.parse(userAddress)); useTonAddress() возвращает адрес в двух форматах: raw (0:abcd...) и friendly (base64url, bounce/non-bounce). Для отображения — friendly. Для сравнения в коде — raw или нормализованный через Address.parse().toString().
Сравнение TON Connect и EVM-кошельков
| Характеристика | TON Connect | MetaMask (EVM) |
|---|---|---|
| Транспорт | Bridge + deep link | JSON-RPC напрямую |
| Отправка транзакции | Сообщение через bridge | RPC-вызов |
| Работа без ноды | Да (bridge буферизирует) | Нет |
| Сложность интеграции | Средняя (TL-B клетки) | Низкая (ABI) |
| Скорость транзакции | 3-5 секунд | 12-15 секунд |
TON Connect побеждает по скорости и автономности, но требует больше внимания к формату сообщений. На практике это даёт экономию времени до 40% на каждую транзакцию за счёт отсутствия необходимости ждать подтверждения ноды.
Что входит в интеграцию Tonkeeper?
| Этап | Результат |
|---|---|
| Настройка manifest.json | Корректный файл на HTTPS |
| Подключение bridge (свой или публичный) | Работающий канал |
| Отправка TON-транзакций | Функция sendTransaction |
| Поддержка Jetton | Передача токенов через TL-B |
| Чтение балансов | TonClient интеграция |
| Документация | API-спецификация для вашей команды |
Мы также обучаем разработчиков работе с TON Connect и предоставляем поддержку на этапе тестирования. Получите консультацию по интеграции — мы оценим вашу задачу бесплатно в течение дня.
Ориентиры по срокам
Базовая интеграция TON Connect (подключение + отправка TON) — полдня. С поддержкой Jetton transfers и чтением балансов — 1-2 дня. Полноценный кошелёк-экран с историей транзакций через TonAPI — 2-3 дня.
Свяжитесь с нами, чтобы обсудить ваш проект. Закажите интеграцию TON Connect под ключ — получите готовое решение с гарантией совместимости.







