Интеграция с TON Connect
TON Connect — это не просто «кошелёк для TON», это протокол связи между dApp и кошельком через bridge сервер. В отличие от EVM где window.ethereum инжектируется в страницу, TON кошельки (Tonkeeper, MyTonWallet, Telegram Wallet) работают как отдельные приложения и общаются с dApp через зашифрованный канал. Это важно понимать архитектурно — соединение устанавливается асинхронно и может быть через QR код или deeplink в Telegram.
Установка и инициализация
npm install @tonconnect/ui-react
Манифест — JSON файл, который кошелёк показывает пользователю при подключении. Должен быть доступен по HTTPS по указанному URL:
// public/tonconnect-manifest.json
{
"url": "https://yourapp.com",
"name": "Your dApp",
"iconUrl": "https://yourapp.com/icon.png"
}
// main.tsx
import { TonConnectUIProvider } from '@tonconnect/ui-react'
root.render(
<TonConnectUIProvider manifestUrl="https://yourapp.com/tonconnect-manifest.json">
<App />
</TonConnectUIProvider>
)
Кнопка подключения и состояние
import { TonConnectButton, useTonConnectUI, useTonAddress, useTonWallet } from '@tonconnect/ui-react'
// Готовая кнопка с UI
<TonConnectButton />
// Кастомная логика
function WalletInfo() {
const address = useTonAddress() // user-friendly формат
const rawAddress = useTonAddress(false) // raw формат для транзакций
const wallet = useTonWallet()
const [tonConnectUI] = useTonConnectUI()
return (
<div>
<p>Адрес: {address}</p>
<p>Кошелёк: {wallet?.device.appName}</p>
<button onClick={() => tonConnectUI.disconnect()}>Disconnect</button>
</div>
)
}
TON адреса существуют в двух форматах: user-friendly (EQD... или UQD...) и raw (0:abc...). User-friendly включает флаг bounceable/non-bounceable. Для отправки на смарт-контракты — bounceable (EQ), для обычных кошельков — non-bounceable (UQ).
Отправка транзакций
TON Connect отправляет сообщения (messages), не транзакции в EVM-смысле. Одна транзакция может содержать несколько сообщений:
import { useTonConnectUI } from '@tonconnect/ui-react'
import { toNano } from '@ton/ton'
function SendTon() {
const [tonConnectUI] = useTonConnectUI()
async function sendTransaction() {
const transaction = {
validUntil: Math.floor(Date.now() / 1000) + 360, // 6 минут
messages: [
{
address: 'EQD...contractAddress',
amount: toNano('0.05').toString(), // в нанотонах
payload: 'te6ccgEBAQEAAgAAAA==', // base64 BOC, опционально
}
]
}
const result = await tonConnectUI.sendTransaction(transaction)
// result.boc — BOC подписанной транзакции
}
}
payload — это BOC (Bag of Cells), сериализованная структура для вызова контракта. Для построения payload используется @ton/ton:
import { beginCell } from '@ton/ton'
// Пример: вызов jetton transfer
const body = beginCell()
.storeUint(0xf8a7ea5, 32) // op code transfer
.storeUint(0, 64) // query_id
.storeCoins(toNano('10')) // amount jettons
.storeAddress(destinationAddress)
.storeAddress(responseAddress)
.storeBit(false) // no custom payload
.storeCoins(toNano('0.01')) // forward TON amount
.storeBit(false) // no forward payload
.endCell()
Проверка соединения и восстановление сессии
TON Connect автоматически восстанавливает сессию при перезагрузке страницы (сохраняет в localStorage). Для проверки статуса подключения:
import { useTonConnectUI } from '@tonconnect/ui-react'
const [tonConnectUI] = useTonConnectUI()
// Подписка на изменения статуса
useEffect(() => {
const unsubscribe = tonConnectUI.onStatusChange((wallet) => {
if (wallet) {
console.log('Connected:', wallet.account.address)
} else {
console.log('Disconnected')
}
})
return unsubscribe
}, [tonConnectUI])
Telegram Mini App контекст
В Telegram Mini App TON Connect работает через Telegram Wallet напрямую — без QR кода. TonConnectUIProvider автоматически определяет контекст и показывает правильный UI. Для Telegram Web App нужно добавить @twa-dev/sdk и инициализировать window.Telegram.WebApp.ready() до рендера провайдера.







