Інтеграція з 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), серіалізована структура для виклику контракту. Використовуйте @ton/ton для побудови payload:
import { beginCell } from '@ton/ton'
// Приклад: виклик jetton transfer
const body = beginCell()
.storeUint(0xf8a7ea5, 32) // op code transfer
.storeUint(0, 64) // query_id
.storeCoins(toNano('10')) // кількість jettons
.storeAddress(destinationAddress)
.storeAddress(responseAddress)
.storeBit(false) // без custom payload
.storeCoins(toNano('0.01')) // forward TON кількість
.storeBit(false) // без 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() перед рендером провайдера.







