Telegram Mini Apps Architecture
Что такое Mini Apps
Telegram Mini Apps (TMAs) — web-приложения, встроенные в Telegram. Работают как обычные web apps, но с доступом к Telegram API и TON Wallet.
Authentication: initData
Telegram передаёт Mini App signed user data (initData):
initData содержит:
user: { id, first_name, last_name, username, language_code }
auth_date: timestamp
hash: HMAC-SHA256 signature (key = bot_token)
Backend validation:
1. Парсить initData (URL-encoded string)
2. Собрать data_check_string (отсортированные поля)
3. Вычислить secret_key = HMAC-SHA256(bot_token, "WebAppData")
4. Вычислить hash = HMAC-SHA256(secret_key, data_check_string)
5. Сравнить hash с переданным → если совпадает, данные authentic
6. Проверить auth_date (не старше X минут)
Валидация initData — ОБЯЗАТЕЛЬНА на backend
Никогда не доверяйте initData без проверки подписи. Клиент может подделать user_id. Только backend с bot_token может проверить HMAC-SHA256 подпись. Без этого — полный auth bypass.
TON Connect: Wallet Integration
TON Connect — протокол подключения кошелька к Mini App:
TON Connect Flow:
1. Mini App показывает "Connect Wallet" кнопку
2. User выбирает wallet (Tonkeeper, TON Space)
3. Wallet открывается → user подтверждает connection
4. Mini App получает wallet address
5. Для транзакций: Mini App → send tx request → Wallet → user confirms → tx signed → broadcast
Security:
- User контролирует private keys (не Mini App!)
- Каждая транзакция требует подтверждения в wallet
- Mini App не имеет доступа к private keys
TON Connect signData: off-chain подписи
Зачем не-транзакционная подпись
В классическом TON Connect все взаимодействия — транзакции, которые отправляются on-chain и платят gas. Но многие сценарии не требуют on-chain footprint:
- Подтверждение пользовательского intent на backend (“я согласен с условиями”).
- Подпись для off-chain auth (вход в dApp без cookie).
- Создание подписи для off-chain ордера в DEX (signed limit order, executed позже).
- Подтверждение действий в Mini App без on-chain записи.
signData (TON Connect 3.4) позволяет dApp запросить у кошелька подпись произвольных данных. Это не транзакция — ничего не отправляется on-chain, gas не тратится. Но подпись криптографически верифицируется и привязана к адресу кошелька.
signData flow
signData request:
1. Mini App → TON Connect SDK: signData({
type: "text",
text: "Confirm withdrawal of 100 USDT"
})
2. SDK → Wallet (Tonkeeper, etc): show signing UI
3. User confirms in wallet
4. Wallet signs: ed25519(private_key, payload + domain + timestamp)
5. SDK → Mini App: { signature, address, timestamp, domain, payload }
6. Mini App → Backend: { signature, address, payload }
7. Backend verifies signature off-chain (или передаёт в смарт-контракт для on-chain действия)
Поддерживаемые типы данных
| Тип | Использование |
|---|---|
text | Простое сообщение: “Confirm 2FA setup”, “Sign in to MyApp” |
binary | Произвольные байты, обычно hash’ы или structured data |
cell | TON cell с TL-B schema — wallet может декодировать и показать содержимое пользователю |
signData генерирует подпись тем же ключом, что и транзакции
Тот же ed25519 private key, что подписывает on-chain транзакции, подписывает и signData. Но signData payload не валиден как TON message — кошелёк добавляет prefix/domain, который защищает от replay (нельзя превратить signData в реальную транзакцию). Это безопасно по дизайну.
Design pattern: signed off-chain order
Off-chain limit order (DEX):
User создаёт ордер: "Sell 100 TON for 350 USDT, expires 2026-05-01"
Mini App:
payload = TL-B encode(ORDER_TYPE, amount_in, amount_out, expiry, nonce)
signature = signData(payload)
Submit к Order Book (off-chain backend)
Solver/Matcher (off-chain):
Match orders, prepare execution
При фактическом execution:
Submit on-chain: signed_order + counterparty_signature → contract
Contract verifies подпись → executes swap
Преимущество:
- User создал 1000 ордеров без 1000 транзакций
- Cancel = просто не подписывать execution; оригинальная подпись expires
- Только matched orders попадают on-chain → меньше gas
Tonkeeper Battery: gasless transactions
Проблема: новый user без TON
Чтобы совершить любую транзакцию на TON, пользователю нужен TON для оплаты gas. Но новый пользователь, пришедший через Telegram Mini App, не имеет TON — он пришёл, чтобы получить airdrop USDT, или купить NFT за Telegram Stars, или claim’ить reward в Mini App.
Требование “сначала купи TON, чтобы оплатить gas” ломает onboarding для миллионов non-crypto пользователей.
Решение: third-party operator оплачивает gas
Tonkeeper Battery — система, при которой:
- User держит USDT (или другой Jetton) в Tonkeeper.
- При транзакции wallet строит сообщение, которое включает малую плату оператору в USDT.
- Третья сторона (relay/operator) получает это сообщение, оплачивает gas в TON и пересылает on-chain.
- После выполнения — recipient получает USDT, оператор получает свою комиссию в USDT.
Battery flow (gasless USDT transfer):
User → Wallet:
intent: send 100 USDT to Bob
Wallet (W5 wallet contract):
build internal message:
output[0]: 100 USDT → Bob
output[1]: 0.1 USDT → Battery operator (fee)
sign with user's key
Wallet → Battery API (off-chain):
signed message + payload
Battery operator:
validate message
pay TON gas from operator's TON balance
broadcast to TON
On-chain:
Bob receives 100 USDT
Operator receives 0.1 USDT (compensates gas + margin)
User: 0 TON balance change
Что делает W5 wallet
Tonkeeper Battery работает благодаря wallet contract version 5 (W5) — стандарту wallet’а, который TON Core и Tonkeeper финализировали в июле 2024:
- Plugins/extensions: W5 поддерживает делегирование операций и подписку на сервисы (gasless transactions — один из плагинов).
- Multi-output messages: до 255 outgoing messages в одной транзакции.
- Signed by user key, but can be paid by anyone: the W5 design позволяет, чтобы gas платил не подписант, а relayer.
Design implications для Mini App
| Сценарий | Без Battery | С Battery |
|---|---|---|
| Onboarding non-crypto user | Купи TON → потом claim | Сразу claim в Mini App |
| USDT-native dApp | Нужно держать TON для gas | Достаточно USDT |
| Subscription payments | Каждый месяц проверять баланс TON | Авто-charge в USDT |
| Mass-market mini-app | High drop-off на “купи gas TON” | Smooth onboarding |
Battery + signData + Mintless = идеальный onboarding
Комбинация трёх паттернов даёт frictionless UX для нового пользователя:
- Mintless airdrop — токены “появляются” без mint фазы.
- Battery — первый transfer/claim не требует TON для gas.
- signData — подпись для off-chain действий не тратит gas.
Это превращает Mini App в инструмент для миллионов non-crypto пользователей. Архитектурно — закладывайте все три паттерна в дизайн с самого начала.
Scaling Mini Apps
Challenge: миллионы пользователей
Telegram Mini Apps могут получить миллионы пользователей за дни (Notcoin: 35M+). Backend должен масштабироваться:
Scaling Stack:
├── CDN: static assets (JS, CSS, images)
├── Load Balancer: distribute API requests
├── Stateless API Servers: horizontally scalable
├── Cache Layer: Redis for session, leaderboard, hot data
├── Database: PostgreSQL/MongoDB for persistent state
├── Queue: для async operations (NFT minting, rewards)
└── TON Integration: async tx submission + indexer for confirmation
Design Pattern: Off-chain Game, On-chain Rewards
Game Architecture (Hamster Kombat style):
Off-chain (backend):
- User progress, scores, achievements
- Game logic, anti-cheat
- Leaderboard (Redis sorted set)
- Session management
On-chain (TON):
- Claim rewards (verified by backend signature)
- NFT achievements (SBT)
- Token distribution
- Staking for boosts
Bridge: Backend signs reward data → user submits to contract →
contract verifies signature → mint/transfer
Payment Integration
Telegram Stars vs TON Payments
| Аспект | Telegram Stars | TON Direct |
|---|---|---|
| UX | In-app purchase (like App Store) | TON Connect → wallet confirm |
| Fees | ~30% (Apple/Google cut) | ~$0.007 (TON tx fee) |
| Currency | Stars (fiat equivalent) | TON, Jettons, USDt |
| Refunds | Telegram handles | Custom logic needed |
| Best for | Digital goods, subscriptions | DeFi, NFT, crypto-native |
Payment Flow Design
TON Payment Flow:
1. Backend creates invoice (amount, description, callback)
2. Frontend → TON Connect → send payment tx
3. TON tx confirmed on-chain
4. Backend indexer detects payment → credit user account
5. Backend sends confirmation to frontend
Important: check payment AMOUNT and DESTINATION
[NO] Trust frontend that payment was made
[OK] Verify on-chain via indexer/API
Anti-abuse Patterns
Rate Limiting
Rate limits:
API calls: 100 req/sec per user
Game actions: 10 actions/sec per user
Reward claims: 1 per hour per user
Implementation: Redis sliding window
Sybil Protection
Sybil resistance:
- Telegram Premium requirement
- Phone number verification (via Telegram)
- Minimum account age
- On-chain activity requirement (TON tx history)
- CAPTCHA for suspicious activity
Системный дизайн Mini App опирается на конкретный API Telegram WebApp — от initData и MainButton до lifecycle событий. Базовый разбор API и архитектуры WebView есть в курсе по TON.
Telegram Mini Apps: архитектураMini Apps 2.0 (2025) добавляет полноэкранный режим, motion-сенсоры и расширенный набор возможностей — эти изменения важно учитывать при проектировании новых приложений.
Mini Apps 2.0: новые возможности