Интеграция кошельков
Интеграция кошелька — это первое, что видит пользователь при взаимодействии с вашим dApp. От качества этой интеграции зависит первое впечатление и конверсия. Плавное подключение, корректное отображение адреса и баланса, обработка отключения — всё это формирует доверие пользователя.
В предыдущем уроке мы изучили архитектуру bridge-протокола TON Connect 2.0. Теперь перейдём к практике — подключим кошелёк к React-приложению с помощью SDK @tonconnect/ui-react.
tonconnect-manifest.json
Первый шаг — создать файл манифеста, описывающий ваше приложение. Кошелёк покажет эту информацию пользователю при запросе на подключение:
{
"url": "https://myapp.example.com",
"name": "My TON dApp",
"iconUrl": "https://myapp.example.com/icon-192.png"
}
| Поле | Описание | Требования |
|---|---|---|
url | URL вашего приложения | HTTPS, без trailing slash |
name | Название приложения | Отображается в кошельке при подключении |
iconUrl | Иконка приложения | PNG/JPG, минимум 180x180px, абсолютный URL |
Разместите файл в публичной директории вашего приложения: public/tonconnect-manifest.json.
Хостите manifest на том же домене, что и dApp
Кошельки проверяют, что url в манифесте совпадает с доменом, откуда пришёл ConnectRequest. Если manifest на другом домене, могут возникнуть проблемы с CORS и верификацией.
Установка SDK
npm install @tonconnect/ui-react
Пакет @tonconnect/ui-react предоставляет:
- TonConnectUIProvider — контекст-провайдер для всего приложения
- TonConnectButton — готовая кнопка подключения/отключения кошелька
- React-хуки — для управления соединением и отправки транзакций
TonConnectUIProvider
Оберните корневой компонент приложения в TonConnectUIProvider, указав URL манифеста:
import { TonConnectUIProvider } from '@tonconnect/ui-react';
function App() {
return (
<TonConnectUIProvider manifestUrl="https://myapp.example.com/tonconnect-manifest.json">
<Header />
<Main />
</TonConnectUIProvider>
);
}
Provider инициализирует SDK, проверяет наличие сохранённой сессии и управляет состоянием подключения для всех дочерних компонентов.
TonConnectButton
Самый простой способ добавить подключение кошелька — использовать готовый компонент TonConnectButton:
import { TonConnectButton } from '@tonconnect/ui-react';
function Header() {
return (
<header>
<h1>My dApp</h1>
<TonConnectButton />
</header>
);
}
TonConnectButton автоматически:
- Показывает кнопку “Connect Wallet” для неподключённых пользователей
- Отображает QR-код или список кошельков при нажатии
- После подключения показывает адрес кошелька и кнопку отключения
- Обновляет состояние при подключении/отключении
Обнаружение кошельков
При нажатии на кнопку подключения SDK показывает список доступных кошельков. Откуда он берётся?
Три источника кошельков
1. Injected wallets
Расширения браузера (TON Wallet Extension)
window.ton или window.tonconnect
2. External wallets (bridge)
Мобильные кошельки (Tonkeeper, MyTonWallet)
Подключение через QR-код / Universal Link
3. Deeplink wallets
Кошельки на том же устройстве
Подключение через deeplink (ton://...)
SDK автоматически определяет injected-кошельки и загружает список внешних кошельков из реестра. Пользователь видит единый интерфейс выбора.
Отслеживание состояния подключения
Используйте хук useTonWallet() для получения информации о подключённом кошельке:
import { useTonWallet } from '@tonconnect/ui-react';
function WalletInfo() {
const wallet = useTonWallet();
if (!wallet) {
return <p>Кошелёк не подключён</p>;
}
return (
<div>
<p>Кошелёк: {wallet.device.appName}</p>
<p>Платформа: {wallet.device.platform}</p>
<p>Адрес: {wallet.account.address}</p>
<p>Сеть: {wallet.account.chain === '-239' ? 'mainnet' : 'testnet'}</p>
</div>
);
}
Хук возвращает:
null— кошелёк не подключён- Объект
Wallet— с информацией об устройстве, аккаунте и сети
Сохранение сессии
SDK автоматически сохраняет сессию в localStorage браузера. При повторном открытии страницы:
- SDK проверяет localStorage на наличие сохранённой сессии
- Если сессия найдена — восстанавливает подключение (без QR-кода)
- Если кошелёк был отключён пользователем — сессия удалена
Проверка восстановления сессии
import { useIsConnectionRestored } from '@tonconnect/ui-react';
import { useTonWallet } from '@tonconnect/ui-react';
function App() {
const connectionRestored = useIsConnectionRestored();
const wallet = useTonWallet();
if (!connectionRestored) {
return <p>Загрузка...</p>;
}
if (!wallet) {
return <p>Подключите кошелёк</p>;
}
return <p>Кошелёк подключён: {wallet.account.address}</p>;
}
Не отображайте UI зависящий от кошелька до восстановления сессии
Без проверки useIsConnectionRestored() пользователь увидит “кошелёк не подключён” на долю секунды, а затем состояние переключится. Всегда показывайте состояние загрузки, пока SDK не завершит проверку localStorage.
Отключение кошелька
Для программного отключения используйте useTonConnectUI():
import { useTonConnectUI } from '@tonconnect/ui-react';
function DisconnectButton() {
const [tonConnectUI] = useTonConnectUI();
const handleDisconnect = async () => {
await tonConnectUI.disconnect();
};
return <button onClick={handleDisconnect}>Отключить кошелёк</button>;
}
При отключении SDK:
- Удаляет сессию из localStorage
- Уведомляет bridge о разрыве соединения
- Обновляет состояние всех хуков (
useTonWallet()возвращаетnull)
Полный пример
Минимальное приложение с подключением кошелька:
import { TonConnectUIProvider, TonConnectButton } from '@tonconnect/ui-react';
import { useTonWallet, useIsConnectionRestored } from '@tonconnect/ui-react';
function WalletStatus() {
const wallet = useTonWallet();
const connectionRestored = useIsConnectionRestored();
if (!connectionRestored) {
return <div>Проверяем подключение...</div>;
}
if (!wallet) {
return <div>Подключите кошелёк для продолжения</div>;
}
const address = wallet.account.address;
const shortAddress = address.slice(0, 6) + '...' + address.slice(-4);
return (
<div>
<p>Подключён: {shortAddress}</p>
<p>Кошелёк: {wallet.device.appName}</p>
</div>
);
}
function App() {
return (
<TonConnectUIProvider
manifestUrl="https://myapp.example.com/tonconnect-manifest.json"
>
<header>
<h1>My TON dApp</h1>
<TonConnectButton />
</header>
<main>
<WalletStatus />
</main>
</TonConnectUIProvider>
);
}
Итоги
| Компонент | Назначение |
|---|---|
tonconnect-manifest.json | Описание dApp для кошелька (url, name, iconUrl) |
TonConnectUIProvider | Контекст-провайдер SDK, оборачивает всё приложение |
TonConnectButton | Готовая кнопка подключения/отключения |
useTonWallet() | Хук: информация о подключённом кошельке (или null) |
useIsConnectionRestored() | Хук: завершена ли проверка сохранённой сессии |
useTonConnectUI() | Хук: прямой доступ к SDK (disconnect, sendTransaction) |
В следующем уроке мы используем установленное соединение для отправки транзакций — переводов TON и вызовов смарт-контрактов.
Частые ошибки
- Не показывают QR-код для мобильных кошельков на десктопе: пользователям Tonkeeper нужен QR для подключения с телефона.
- Забывают обработать сценарий отключения кошелька (disconnect): после отключения приложение должно очистить состояние и вернуться к экрану подключения.
- Не отображают сокращённый адрес кошелька (EQ…abc) после подключения: пользователь должен видеть, какой кошелёк подключён.
- Используют raw-адрес вместо user-friendly формата в UI, что запутывает пользователей и создаёт риск ошибок при копировании.
Проверка знанийПочему важно проверять useIsConnectionRestored() перед отображением UI, зависящего от состояния кошелька?
Check Your Understanding
Finished the lesson?
Mark it as complete to track your progress
Войдите чтобы оценить урок