Как подключить TON Connect в Telegram Mini App
Продвинутое4 минРедакция Innovialabs
Коротко
Подключите кошелёк через @tonconnect/ui с манифестом, подтверждайте владение адресом через ton_proof с проверкой на сервере, отправляйте транзакции через sendTransaction и считайте оплату завершённой только после проверки в блокчейне — а до запуска разберитесь с правилами Telegram и местным регулированием.
Как это устроено
TON Connect — протокол, по которому Mini App связывается с кошельком пользователя (Telegram Wallet, Tonkeeper и другие). Приложение никогда не получает ключи — оно только просит кошелёк подписать данные или транзакцию.
Полный сценарий состоит из четырёх частей:
- Манифест — JSON-файл с описанием вашего приложения.
- Подключение кошелька — пользователь выбирает кошелёк и подтверждает.
- ton_proof — криптографическое доказательство, что адрес действительно принадлежит пользователю. Проверяется на бэкенде.
- Транзакции — кошелёк подписывает и отправляет, сервер проверяет результат в блокчейне.
Шаг 1. Манифест и подключение
Разместите tonconnect-manifest.json по публичному HTTPS-адресу:
{
"url": "https://example.com",
"name": "Example Shop",
"iconUrl": "https://example.com/icon-180.png",
"termsOfUseUrl": "https://example.com/terms",
"privacyPolicyUrl": "https://example.com/privacy"
}
В React-приложении используйте @tonconnect/ui-react:
import { TonConnectUIProvider, TonConnectButton } from "@tonconnect/ui-react";
export function App() {
return (
<TonConnectUIProvider
manifestUrl="https://example.com/tonconnect-manifest.json"
actionsConfiguration={{ twaReturnUrl: "https://t.me/your_bot/app" }}
>
<TonConnectButton />
</TonConnectUIProvider>
);
}
twaReturnUrl возвращает пользователя в Mini App после подтверждения во внешнем кошельке. Хуки useTonWallet() и useTonAddress() дают текущее подключение.
Шаг 2. ton_proof: проверка владения адресом
Адрес из useTonAddress() — это данные с клиента. Подделать их так же просто, как initDataUnsafe. Если адрес используется для входа, привязки к аккаунту или начисления чего-либо, нужен ton_proof.
Поток:
- Бэкенд генерирует случайный payload (nonce) с коротким сроком жизни и сохраняет его.
- Фронтенд передаёт его в запрос подключения.
- Кошелёк подписывает сообщение, содержащее ваш домен, время, адрес и payload.
- Фронтенд отправляет подпись на бэкенд.
tonConnectUI.setConnectRequestParameters({ state: "loading" });
const payload = await fetch("/api/ton-proof/payload").then((r) => r.text());
tonConnectUI.setConnectRequestParameters({ state: "ready", value: { tonProof: payload } });
tonConnectUI.onStatusChange((wallet) => {
const item = wallet?.connectItems?.tonProof;
if (wallet && item && "proof" in item) {
fetch("/api/ton-proof/check", {
method: "POST",
body: JSON.stringify({ account: wallet.account, proof: item.proof }),
});
}
});
Что проверяет бэкенд:
- payload выдан вами, не просрочен и ещё не использован;
- домен в доказательстве совпадает с вашим;
- timestamp свежий;
- публичный ключ получен из
walletStateInitили запросом к контракту кошелька, и из него действительно выводится заявленный адрес; - подпись Ed25519 верна для сообщения, собранного по спецификации TON Connect.
Сборка сообщения для подписи — место, где легко ошибиться в порядке байтов. Опирайтесь на официальные примеры бэкенда TON Connect, а не на самописную реализацию. После проверки выдайте собственный токен сессии.
Шаг 3. Отправка транзакции
import { beginCell, toNano } from "@ton/core";
const comment = beginCell().storeUint(0, 32).storeStringTail(`order:${orderId}`).endCell();
await tonConnectUI.sendTransaction({
validUntil: Math.floor(Date.now() / 1000) + 300,
messages: [
{
address: MERCHANT_ADDRESS,
amount: toNano("1.5").toString(),
payload: comment.toBoc().toString("base64"),
},
],
});
amount— в нанотонах, строкой.- Комментарий с номером заказа помогает сопоставить платёж с заказом.
validUntilограничивает время, за которое пользователь может подтвердить транзакцию.
Главное правило: успешный ответ sendTransaction значит, что кошелёк отправил сообщение, но не то, что деньги пришли. Отметку «оплачено» ставит бэкенд, найдя входящую транзакцию на ваш адрес через индексатор или API блокчейна и сверив сумму, адрес и комментарий. Обработка должна быть идемпотентной: одна транзакция — один заказ.
Правила и регулирование
Технически подключить TON просто. Сложнее юридическая часть.
- Правила Telegram. Для цифровых товаров и услуг внутри Mini Apps Telegram требует оплату в Stars. Крипто-функции в экосистеме Mini Apps ориентированы на TON и TON Connect. Проверяйте актуальные правила перед запуском.
- Местное законодательство. Во многих странах, включая Узбекистан, оборот криптоактивов регулируется отдельно, а услуги с ними требуют лицензии. Приём крипты в качестве оплаты может быть ограничен.
- KYC и AML. В зависимости от модели бизнеса может понадобиться идентификация клиентов и проверка происхождения средств.
- Налоги и бухгалтерия. Нужно понимать, как учитывать поступления и по какому курсу.
- Необратимость. Транзакцию в блокчейне нельзя отменить — продумайте возвраты отдельной процедурой.
- Волатильность. Цена в TON меняется: фиксируйте курс на короткое время или используйте стейблкоины, если это допустимо.
До разработки получите консультацию юриста по вашей юрисдикции и модели.