diff --git a/package.json b/package.json index 708211a..739b0f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pezkuwi-telegram-miniapp", - "version": "1.0.247", + "version": "1.0.248", "type": "module", "description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards", "author": "Pezkuwichain Team", diff --git a/src/App.tsx b/src/App.tsx index dbed0a3..7455fc9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -59,6 +59,9 @@ const IS_CITIZENSHIP_REFERRAL = const IS_CITIZEN_PAGE = PAGE_PARAM === 'citizen' || window.location.pathname === '/citizens' || IS_CITIZENSHIP_REFERRAL; const IS_EXPLORER_PAGE = window.location.pathname.replace(/\/$/, '') === '/explorer'; +// The bot's "Create Wallet" button opens ?page=wallet, so the seed is made here, +// on the device, and never by the bot. +const START_SECTION: Section = PAGE_PARAM === 'wallet' ? 'wallet' : 'announcements'; export default function App() { if (IS_CITIZEN_PAGE) { @@ -81,7 +84,7 @@ export default function App() { } function MainApp() { - const [activeSection, setActiveSection] = useState
('announcements'); + const [activeSection, setActiveSection] = useState
(START_SECTION); const { t } = useTranslation(); const handleNavClick = (item: NavItem) => { diff --git a/src/version.json b/src/version.json index ac54596..4dc64c2 100644 --- a/src/version.json +++ b/src/version.json @@ -1,5 +1,5 @@ { - "version": "1.0.247", - "buildTime": "2026-10-12T04:28:57.503Z", - "buildNumber": 1791779337503 + "version": "1.0.248", + "buildTime": "2026-10-24T22:35:17.295Z", + "buildNumber": 1792881317295 } diff --git a/supabase/functions/telegram-bot/index.ts b/supabase/functions/telegram-bot/index.ts index 0cc6985..97de130 100644 --- a/supabase/functions/telegram-bot/index.ts +++ b/supabase/functions/telegram-bot/index.ts @@ -7,13 +7,6 @@ */ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'; -// The keyring alone, not @pezkuwi/api: the API package pulls in every type -// definition and rxjs, which made each worker boot take ~40 s and ~300 MB for -// a bot whose only chain work is deriving an address. -import { Keyring } from 'npm:@pezkuwi/keyring@14.0.25'; -import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.25'; -import * as bip39 from 'https://esm.sh/@scure/bip39@1.2.1'; -import { wordlist } from 'https://esm.sh/@scure/bip39@1.2.1/wordlists/english'; // ── Bot configuration ─────────────────────────────────────────────── const BOT_TOKENS: Record = { @@ -525,8 +518,8 @@ interface TelegramUpdate { // ── Telegram API helper ───────────────────────────────────────────── async function sendTelegramRequest(token: string, method: string, body: Record) { - // Only the method and chat are logged. Bodies carry what users wrote, the - // assistant's replies and, from the create-wallet button, a seed phrase. + // Only the method and chat are logged. Bodies carry what users wrote and the + // assistant's replies. console.log(`[Telegram] Calling ${method}`, `chat=${body.chat_id ?? '-'}`); if (!token) { @@ -601,11 +594,12 @@ async function sendKrdWelcome(token: string, chatId: number) { const keyboard = { inline_keyboard: [ - // Row 1: Create Wallet (callback - bot generates wallet in chat) + // Row 1: Create Wallet. Opens the mini app's wallet screen, which makes + // the seed on the user's device; the bot never sees it. [ { text: '🔐 Create Wallet / Cûzdan Biafirîne', - callback_data: 'create_wallet', + web_app: { url: walletAppUrl(appUrl) }, }, ], // Row 2: Languages (top row) @@ -702,46 +696,12 @@ async function sendDksWelcome(token: string, chatId: number) { }); } -// ── Create wallet handler ─────────────────────────────────────────── -async function handleCreateWallet(token: string, chatId: number) { - try { - await cryptoWaitReady(); - - const mnemonic = bip39.generateMnemonic(wordlist, 128); - const keyring = new Keyring({ type: 'sr25519' }); - const pair = keyring.addFromUri(mnemonic); - const address = pair.address; - - const walletMessage = ` -🔐 Cûzdanê Te Hate Afirandin! -Your Wallet Has Been Created! - -📍 Address / Navnîşan: -${address} - -🔑 Seed Phrase (12 words): -${mnemonic} - -⚠️ GIRÎNG / IMPORTANT: -Ev 12 peyvan binivîsin û li cihekî ewle bihêlin. -Kesî re nîşan nedin! Eger winda bikin, cûzdanê xwe winda dikin. - -Write down these 12 words and keep them safe. -Never share them! If you lose them, you lose your wallet. -`; - - await sendTelegramRequest(token, 'sendMessage', { - chat_id: chatId, - text: walletMessage, - parse_mode: 'HTML', - }); - } catch (error) { - console.error('[Bot] Wallet generation error:', error); - await sendTelegramRequest(token, 'sendMessage', { - chat_id: chatId, - text: '❌ Wallet creation failed. Please try again.', - }); - } +// ── Create wallet ─────────────────────────────────────────────────── +// The wallet is made in the mini app, on the user's device. The bot used to +// generate the seed here and send it as a chat message, which put every new +// wallet's seed through this server and left it in Telegram's cloud history. +function walletAppUrl(appUrl: string): string { + return `${appUrl}/?page=wallet`; } // ── Callback handler ──────────────────────────────────────────────── @@ -752,11 +712,25 @@ async function handleCallbackQuery( chatId: number | undefined ) { if (data === 'create_wallet' && chatId) { + // Legacy button on old welcome messages: point it at the mini app instead + // of making a seed here. await sendTelegramRequest(token, 'answerCallbackQuery', { callback_query_id: callbackQueryId, - text: '🔐 Creating your wallet...', }); - await handleCreateWallet(token, chatId); + await sendTelegramRequest(token, 'sendMessage', { + chat_id: chatId, + text: '🔐 Cûzdanê xwe li ser telefona xwe biafirîne. / Create your wallet on your own phone.', + reply_markup: { + inline_keyboard: [ + [ + { + text: '🔐 Create Wallet / Cûzdan Biafirîne', + web_app: { url: walletAppUrl(MINI_APP_URLS.krd) }, + }, + ], + ], + }, + }); } else if (data === 'playstore_coming_soon') { // Legacy button on old messages - the app is live now, send the real link await sendTelegramRequest(token, 'answerCallbackQuery', {