Everyone's talking about AI agents. But most articles stop at the proof-of-concept. We actually shipped three production Telegram Mini Apps with AI components — a DCA investment bot, a social asset marketplace, and an AI interior design tool — each serving real users on TON blockchain.
Here's what nobody tells you about scaling Telegram Mini Apps with AI in production.
Why Telegram Mini Apps?
Telegram has 950M+ monthly active users. Telegram Mini Apps (TMAs) run inside Telegram with zero install friction. Combine that with TON blockchain for payments and you get a distribution channel most web apps would kill for.
But TMAs come with brutal constraints:
- No service workers — forget your PWA caching strategies
- Limited viewport — 400px width is your reality
- WebView quirks — different behavior on iOS vs Android vs Desktop
- Cold starts matter — users tap, wait 2 seconds, leave
We learned all of this the hard way across three products.
Case 1: TON DCA — Non-Custodial Investment Protocol
The problem: Users wanted dollar-cost averaging into TON tokens without trusting a centralized service with their funds.
The architecture:
┌─────────────────┐ ┌──────────────┐ ┌─────────────┐
│ Telegram Mini │────▶│ NestJS │────▶│ TON Smart │
│ App (TMA) │ │ Indexer │ │ Contract │
│ + TonConnect │ │ │ │ (Tact) │
└─────────────────┘ └──────────────┘ └─────────────┘
│
┌─────▼─────┐
│ STON.fi │
│ v2.1 DEX │
└───────────┘
The smart contract uses a MasterChef-style index model for O(1) complexity on reward distribution. Instead of iterating over every user position (which gets expensive fast on-chain), we maintain a global accumulator index:
// Simplified Tact logic for DCA execution
contract DCAVault {
globalIndex: Int = 0;
totalDeposited: Int = 0;
receive(msg: ExecuteDCA) {
// Swap via STON.fi v2.1
let swapResult = self.executeSwap(msg.amount, msg.tokenOut);
// Update global index — O(1) regardless of user count
self.globalIndex += swapResult.received * PRECISION / self.totalDeposited;
}
get fun pendingRewards(user: Address): Int {
let position = self.positions.get(user);
return (self.globalIndex - position.lastIndex) * position.deposited / PRECISION;
}
}
The proxy-ton mechanism was our secret weapon. TON's native coin can't be directly handled like jettons in smart contracts. We wrap/unwrap TON transparently so users never think about it.
Key lesson: TonConnect integration in TMAs is fragile. The wallet adapter crashes silently on older Android WebViews. We added a health-check ping before every transaction:
async function safeConnect(tonConnect: TonConnect): Promise<boolean> {
try {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error('TonConnect timeout')), 3000)
);
await Promise.race([tonConnect.getWallets(), timeout]);
return true;
} catch {
// Fallback: show deeplink QR
showWalletQR();
return false;
}
}
Case 2: ITOhub — Social Asset Marketplace on TON
ITOhub lets people buy and sell Telegram channels through an escrow smart contract. Think of it as an on-chain marketplace for social media assets.
The hard part: Modeling a deal lifecycle on-chain.
We used a Finite State Machine in FunC:
CREATED → FUNDED → ASSET_TRANSFERRED → PROGRESS_CONFIRMED → COMPLETED
↓ ↓ ↓
CANCELLED DISPUTED DISPUTED → RESOLVED
Each state transition is an on-chain message. The vault holds funds until an oracle confirms the asset transfer (channel ownership change verified via Telegram API).
() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
int op = in_msg_body~load_uint(32);
if (op == op::confirm_transfer) {
throw_unless(403, equal_slices(sender, oracle_address));
throw_unless(400, deal_state == STATE_ASSET_TRANSFERRED);
;; Release funds to seller
deal_state = STATE_COMPLETED;
send_funds(seller_address, deal_amount - platform_fee);
return ();
}
}
Key lesson: On-chain FSMs need escape hatches. We added time-locked auto-resolution: if neither party acts within 72 hours, funds return to the buyer. Without this, we'd have had frozen funds on day one.
Case 3: Obrazno — AI Interior Design SaaS
This one's different. Not blockchain — pure AI. A designer named Maria had interior design expertise but couldn't scale beyond 1-on-1 consultations. We turned her knowledge into a SaaS product.
The stack:
Turborepo Monorepo
├── apps/web (Next.js frontend)
├── apps/api (NestJS 11)
├── packages/ai (OpenAI integration)
└── packages/queue (BullMQ workers)
The AI pipeline:
- User uploads room photo
- AI generates a segmentation mask (walls, floor, furniture)
- User edits mask with our custom editor
- AI in-paints the selected areas with chosen style
- Result feeds into a moodboard generator
The critical optimization was queue architecture. AI image generation takes 15-30 seconds. You can't hold an HTTP connection that long in a TMA WebView — it'll timeout.
// API endpoint — returns immediately
@Post('generate')
async generate(@Body() dto: GenerateDto) {
const job = await this.queue.add('inpaint', {
imageUrl: dto.imageUrl,
mask: dto.mask,
style: dto.style,
}, {
attempts: 3,
backoff: { type: 'exponential', delay: 2000 },
});
return { jobId: job.id }; // Client polls or uses WebSocket
}
// BullMQ Worker — runs separately
@Processor('inpaint')
async process(job: Job) {
const result = await this.openai.images.edit({
image: await fetchBuffer(job.data.imageUrl),
mask: job.data.mask,
prompt: buildPrompt(job.data.style),
size: '1024x1024',
});
await this.notify(job.data.userId, result.data[0].url);
}
Key lesson: BullMQ's exponential backoff saved us from OpenAI rate limits. Without it, concurrent users would cascade-fail. We also cache style embeddings so repeated prompts skip the expensive generation step.
Universal Lessons Across All Three Projects
1. Telegram WebView is Not a Browser
Stop treating it like one. Test on actual devices. The iOS WebView swallows errors silently. Android fragments the experience across Samsung Internet WebView vs Chrome WebView.
Our fix: a lightweight compatibility layer that we now reuse across all TMA projects:
const TMA = {
isReady: () => window.Telegram?.WebApp?.initData !== '',
platform: () => window.Telegram?.WebApp?.platform || 'unknown',
haptic: (type: 'light' | 'medium' | 'heavy') => {
window.Telegram?.WebApp?.HapticFeedback?.impactOccurred(type);
},
close: () => window.Telegram?.WebApp?.close(),
expand: () => window.Telegram?.WebApp?.expand(),
};
2. Cold Start is Your Enemy
Users open your TMA from a chat message. They expect instant response. Every millisecond of white screen is a lost user.
- Skeleton screens — show structure before data loads
-
Prefetch on bot command — when user sends
/start, warm the cache before they tap the Mini App button - Bundle size — under 200KB gzipped or you're dead on mobile networks
3. AI Features Need Graceful Degradation
OpenAI has outages. Models get deprecated. Rate limits spike during peak hours.
Every AI feature should have a non-AI fallback:
- Image generation fails → show curated templates
- Text analysis fails → basic keyword matching
- Recommendation engine down → show popular items
4. On-Chain + Off-Chain Hybrid is the Way
Pure on-chain apps are slow and expensive. Pure off-chain apps lose the trust guarantees. The hybrid approach — settlements on-chain, UX off-chain — is where production apps live.
All three of our projects use this pattern. Even Obrazno (no blockchain) follows the same principle with its queue architecture: the "source of truth" (job queue) is durable, while the UI is optimistic.
The Numbers
Across these three projects:
| Metric | TON DCA | ITOhub | Obrazno |
|---|---|---|---|
| API Response | <100ms | <150ms | <200ms |
| AI Accuracy | N/A | N/A | >90% |
| Concurrent Users | 500+ | 200+ | 100+ |
| Uptime (30d) | 99.7% | 99.5% | 99.8% |
What's Next
We're doubling down on Telegram Mini Apps. The distribution advantage is real — when your app lives where your users already spend 3+ hours a day, acquisition costs drop dramatically.
The intersection of AI + blockchain + messaging apps isn't a gimmick. It's the stack that lets small teams compete with funded startups.
If you're building on TON or need AI integration for your Telegram Mini App — we've been through the trenches. Check out our case studies at gerus-lab.com or reach out directly. We ship production code, not demos.
This article is based on real production experience at Gerus Lab, a development studio specializing in blockchain, AI, and Telegram ecosystem products.
Top comments (1)
Great writeup! The cold start optimization point really resonates. I'm building a Telegram Mini App myself (WhisprMe — anonymous messaging) and keeping the bundle under 200KB was a game-changer for retention.
One thing I'd add: Telegram Stars payments are surprisingly smooth to implement. We use
XTRcurrency with emptyprovider_tokenand the conversion is much higher than traditional payment gateways because users never leave the app. I wrote a step-by-step guide on implementing it if anyone's interested.The TMA compatibility layer idea is also solid — we do something similar with a wrapper around
WebApp.HapticFeedbacksince it silently fails on desktop.