@www.hyperlinks.space/program-kit 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -0
- package/api/ai.ts +111 -0
- package/api/base.ts +117 -0
- package/api/blockchain.ts +58 -0
- package/api/bot.ts +19 -0
- package/api/ping.ts +41 -0
- package/api/releases.ts +162 -0
- package/api/telegram.ts +65 -0
- package/api/tsconfig.json +17 -0
- package/app/_layout.tsx +135 -0
- package/app/ai.tsx +39 -0
- package/app/components/GlobalBottomBar.tsx +447 -0
- package/app/components/GlobalBottomBarWeb.tsx +362 -0
- package/app/components/GlobalLogoBar.tsx +108 -0
- package/app/components/GlobalLogoBarFallback.tsx +66 -0
- package/app/components/GlobalLogoBarWithFallback.tsx +24 -0
- package/app/components/HyperlinksSpaceLogo.tsx +29 -0
- package/app/components/Telegram.tsx +648 -0
- package/app/components/telegramWebApp.ts +359 -0
- package/app/fonts.ts +12 -0
- package/app/index.tsx +102 -0
- package/app/theme.ts +117 -0
- package/app.json +60 -0
- package/assets/icon.ico +0 -0
- package/assets/images/favicon.png +0 -0
- package/blockchain/coffee.ts +217 -0
- package/blockchain/router.ts +44 -0
- package/bot/format.ts +143 -0
- package/bot/grammy.ts +52 -0
- package/bot/responder.ts +620 -0
- package/bot/webhook.ts +262 -0
- package/database/messages.ts +128 -0
- package/database/start.ts +133 -0
- package/database/users.ts +46 -0
- package/docs/ai_and_search_bar_input.md +94 -0
- package/docs/ai_bot_messages.md +124 -0
- package/docs/backlogs/medium_term_backlog.md +26 -0
- package/docs/backlogs/short_term_backlog.md +39 -0
- package/docs/blue_bar_tackling.md +143 -0
- package/docs/bot_async_streaming.md +174 -0
- package/docs/build_and_install.md +129 -0
- package/docs/database_messages.md +34 -0
- package/docs/fonts.md +18 -0
- package/docs/releases.md +201 -0
- package/docs/releases_github_actions.md +188 -0
- package/docs/scalability.md +34 -0
- package/docs/security_plan_raw.md +244 -0
- package/docs/security_raw.md +345 -0
- package/docs/timing_raw.md +63 -0
- package/docs/tma_logo_bar_jump_investigation.md +69 -0
- package/docs/update.md +205 -0
- package/docs/wallets_hosting_architecture.md +257 -0
- package/eas.json +47 -0
- package/eslint.config.js +10 -0
- package/fullREADME.md +159 -0
- package/global.css +67 -0
- package/npmReadMe.md +53 -0
- package/package.json +214 -0
- package/scripts/load-env.ts +17 -0
- package/scripts/migrate-db.ts +16 -0
- package/scripts/program-kit-init.cjs +58 -0
- package/scripts/run-bot-local.ts +30 -0
- package/scripts/set-webhook.ts +67 -0
- package/scripts/test-api-base.ts +12 -0
- package/telegram/post.ts +328 -0
- package/tsconfig.json +17 -0
- package/vercel.json +7 -0
- package/windows/after-sign-windows-icon.cjs +13 -0
- package/windows/build-layout.cjs +72 -0
- package/windows/build-with-progress.cjs +88 -0
- package/windows/build.cjs +2247 -0
- package/windows/cleanup-legacy-appdata-installs.ps1 +91 -0
- package/windows/cleanup-legacy-windows-shortcuts.ps1 +46 -0
- package/windows/cleanup.cjs +200 -0
- package/windows/embed-windows-exe-icon.cjs +55 -0
- package/windows/extractAppPackage.nsh +150 -0
- package/windows/forge/README.md +41 -0
- package/windows/forge/forge.config.js +138 -0
- package/windows/forge/make-with-stamp.cjs +65 -0
- package/windows/forge-cleanup.cjs +255 -0
- package/windows/hsp-app-process.ps1 +63 -0
- package/windows/installer-hooks.nsi +373 -0
- package/windows/product-brand.cjs +42 -0
- package/windows/remove-orphan-uninstall-registry.ps1 +67 -0
- package/windows/run-installed-with-icon-debug.cmd +20 -0
- package/windows/run-win-electron-builder.cjs +46 -0
- package/windows/updater-dialog.html +143 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Security Implementation Plan (Telegram-First Wallet)
|
|
2
|
+
|
|
3
|
+
This file describes a practical implementation plan for the security model defined in `security.md`, focused on the `./app` (Expo / Vercel) codebase and a serverless backend.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Phase 0 – Prerequisites & Plumbing
|
|
8
|
+
|
|
9
|
+
- **0.1. Bot & Mini App configuration**
|
|
10
|
+
- Ensure main Mini App is configured in @BotFather with:
|
|
11
|
+
- `https://hsbexpo.vercel.app` (or new URL) as base.
|
|
12
|
+
- `startapp` support enabled.
|
|
13
|
+
- Confirm `telegram-web-app.js` is loaded in the Mini App shell.
|
|
14
|
+
|
|
15
|
+
- **0.2. Serverless backend basics**
|
|
16
|
+
- Use existing Vercel project (`./app`) API routes:
|
|
17
|
+
- Create a shared util for **Telegram initData validation** (WebApp) in `api/_lib/telegram.ts`:
|
|
18
|
+
- `validateInitData(initData: string): { username: string }`.
|
|
19
|
+
- Create a shared util for **Telegram Login widget validation** (web/native) in `api/_lib/telegram_login.ts`:
|
|
20
|
+
- `validateLoginPayload(payload): { username: string }`.
|
|
21
|
+
|
|
22
|
+
- **0.3. Database**
|
|
23
|
+
- Choose a serverless DB (e.g. Neon, Supabase, PlanetScale, Vercel Postgres).
|
|
24
|
+
- Define tables (supporting **multiple wallets per user**, including app-created and TonConnect-linked):
|
|
25
|
+
- `users`:
|
|
26
|
+
- `telegram_username` (PK or unique, text).
|
|
27
|
+
- `created_at`, `updated_at`.
|
|
28
|
+
- `last_login_at` – last successful Telegram login (any platform).
|
|
29
|
+
- `last_tma_seen_at` – last time user opened the Mini App.
|
|
30
|
+
- `locale` – preferred language (derived from Telegram).
|
|
31
|
+
- `time_zone` (optional, from app settings).
|
|
32
|
+
- `number_of_wallets` – cached count for quick UI/query.
|
|
33
|
+
- `default_wallet` – optional reference/key to the user’s default wallet (e.g. `wallet_address` + `wallet_blockchain` + `wallet_net` tuple or UI identifier).
|
|
34
|
+
- `security_flags` (JSON) – e.g. `{ "high_value_user": true, "require_extra_confirm": false }`.
|
|
35
|
+
- `marketing_opt_in` (bool) – whether user agreed to non-transactional notifications.
|
|
36
|
+
- `wallets`:
|
|
37
|
+
- `telegram_username` (FK to `users`).
|
|
38
|
+
- `address` (text).
|
|
39
|
+
- `blockchain` (text, e.g. `'ton'`).
|
|
40
|
+
- `net` (text, e.g. `'mainnet'`, `'testnet'`).
|
|
41
|
+
- `type` (`'internal' | 'tonconnect' | 'other'`) – app-created vs external/connected.
|
|
42
|
+
- `label` (optional user-friendly name, e.g. “Main wallet”, “Tonkeeper”).
|
|
43
|
+
- `is_default` (bool) – which wallet to show first in UI.
|
|
44
|
+
- Composite PK/unique: (`telegram_username`, `wallet_address`, `wallet_blockchain`, `wallet_net`).
|
|
45
|
+
- `created_at` – when this wallet record was created (first seen / added).
|
|
46
|
+
- `updated_at` – when this wallet record was created (first seen / added).
|
|
47
|
+
- `last_used_at` – last time a transaction was initiated or confirmed with this wallet.
|
|
48
|
+
- `last_seen_balance_at` – last time we refreshed its on-chain balance
|
|
49
|
+
- `source` – 'miniapp', 'tonconnect', 'imported' (how it was added)
|
|
50
|
+
- `notes` – (optional text): free-form user note about this wallet.
|
|
51
|
+
- Timestamps / metadata (last_used_at, etc.).
|
|
52
|
+
- `pending_transactions`:
|
|
53
|
+
- `id` (UUID / text, PK).
|
|
54
|
+
- `telegram_username` (FK to `users`).
|
|
55
|
+
- `wallet_address` (text).
|
|
56
|
+
- `wallet_blockchain` (text).
|
|
57
|
+
- `wallet_net` (text).
|
|
58
|
+
- `payload` (JSONB / text).
|
|
59
|
+
- `status` (`pending | confirmed | rejected | failed`).
|
|
60
|
+
- `created_at`, `updated_at`.
|
|
61
|
+
- Add minimal DB client in `api/_lib/db.ts`.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Phase 1 – Telegram Mini App: Wallet Creation & Device Auth
|
|
66
|
+
|
|
67
|
+
- **1.1. Mini App bootstrap**
|
|
68
|
+
- Create a dedicated Mini App entry screen in Expo web (`app/app/index.tsx` or a nested route) that:
|
|
69
|
+
- Accesses `window.Telegram.WebApp.initData`.
|
|
70
|
+
- Calls a backend endpoint `POST /api/tg/init` to:
|
|
71
|
+
- Validate `initData`.
|
|
72
|
+
- Upsert a bare `users` row if needed (without wallet).
|
|
73
|
+
|
|
74
|
+
- **1.2. Wallet creation flow (TMA)**
|
|
75
|
+
- Implement a React flow in the Mini App:
|
|
76
|
+
- Step 1: Intro + explanation (self-custody, seed phrase).
|
|
77
|
+
- Step 2: Generate mnemonic (client-side) with a TON/crypto library.
|
|
78
|
+
- Step 3: Show mnemonic & confirmation quiz.
|
|
79
|
+
- Step 4:
|
|
80
|
+
- Derive wallet master key from mnemonic.
|
|
81
|
+
- Store it via `Telegram.WebApp.SecureStorage.setItem('wallet_master_key', <key>)`.
|
|
82
|
+
- Derive/encode wallet seed or root key, encrypt with master key → `seed_cipher`.
|
|
83
|
+
- Store `seed_cipher` via `Telegram.WebApp.CloudStorage.setItem('wallet_seed_cipher', <cipher>)`.
|
|
84
|
+
- Derive `wallet_address` from mnemonic/root key.
|
|
85
|
+
- Call `POST /api/wallet/register` with `{ telegram_username, wallet_address }` (initData-validated).
|
|
86
|
+
- Step 5: Success screen explaining:
|
|
87
|
+
- “Wallet created in Telegram; keep your mnemonic safe.”
|
|
88
|
+
- “Use Android/iOS/web to view wallet after logging in with Telegram.”
|
|
89
|
+
|
|
90
|
+
- **1.3. New Telegram device authorization**
|
|
91
|
+
- At Mini App start:
|
|
92
|
+
- Check `SecureStorage.getItem('wallet_master_key')`.
|
|
93
|
+
- If present → user can operate without extra input.
|
|
94
|
+
- If absent but `CloudStorage.getItem('wallet_seed_cipher')` exists:
|
|
95
|
+
- Show “Authorize this device” screen:
|
|
96
|
+
- Prompt for mnemonic once.
|
|
97
|
+
- Derive new master key, store in `SecureStorage`.
|
|
98
|
+
- Optionally re-encrypt `seed_cipher` (or just reuse old one).
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Phase 2 – iOS/Android App Flow (Single App)
|
|
103
|
+
|
|
104
|
+
(All implemented inside `./app` using Expo Router / React Native.)
|
|
105
|
+
|
|
106
|
+
- **2.1. Local state**
|
|
107
|
+
- Add a simple secure storage wrapper (e.g. `expo-secure-store`):
|
|
108
|
+
- Keys:
|
|
109
|
+
- `telegram_username`
|
|
110
|
+
- `wallet_address`
|
|
111
|
+
- Add a React context or hook `useCurrentUser()` that:
|
|
112
|
+
- On app start, reads these keys.
|
|
113
|
+
- Exposes `state: 'anonymous' | 'linked'`, `telegram_username`, `wallet_address`.
|
|
114
|
+
|
|
115
|
+
- **2.2. “Log in with Telegram” screen**
|
|
116
|
+
- Create a route (e.g. `app/app/login/telegram.tsx`) used on mobile startup when `state === 'anonymous'`:
|
|
117
|
+
- Copy text from `security.md`:
|
|
118
|
+
- Explain benefits of Telegram-based wallet creation and storage.
|
|
119
|
+
- Buttons:
|
|
120
|
+
- **Open Telegram to create wallet**:
|
|
121
|
+
- Use `Linking.openURL('https://t.me/<bot_username>?startapp=wallet_onboarding')`.
|
|
122
|
+
- **I already created my wallet in Telegram / Log in with Telegram**:
|
|
123
|
+
- Opens a WebView or browser to hosted login page (e.g. `/login/telegram`).
|
|
124
|
+
|
|
125
|
+
- **2.3. Telegram Login for Websites (web page + API)**
|
|
126
|
+
- Create a web page (static route in `./app` or separate) that:
|
|
127
|
+
- Embeds the Telegram Login widget configured for your bot & domain.
|
|
128
|
+
- On success, posts the payload (via `data-onauth` callback) to `POST /api/login/telegram`.
|
|
129
|
+
- `POST /api/login/telegram`:
|
|
130
|
+
- Validates login payload (`hash` + `auth_date`) per [Telegram widget docs](https://core.telegram.org/widgets/login).
|
|
131
|
+
- Extracts `username`.
|
|
132
|
+
- Looks up `users` by `telegram_username`.
|
|
133
|
+
- Responds with:
|
|
134
|
+
- On success: `{ telegram_username, wallet_address }`.
|
|
135
|
+
- On missing wallet: `{ error: 'NO_WALLET' }`.
|
|
136
|
+
- In the mobile WebView:
|
|
137
|
+
- When login completes, post a message back to the React Native layer with the above payload.
|
|
138
|
+
- Native side saves `telegram_username` + `wallet_address` via secure storage and updates `useCurrentUser()` state.
|
|
139
|
+
|
|
140
|
+
- **2.4. Main wallet UI on mobile**
|
|
141
|
+
- When `useCurrentUser()` reports `state === 'linked'`:
|
|
142
|
+
- Show wallet balances / positions (read-only) via:
|
|
143
|
+
- Direct chain APIs or your own serverless `GET /api/wallet/state?address=...`.
|
|
144
|
+
- For any **sensitive action** (swap, send, etc.) use the serverless + bot confirmation flow (Phase 3).
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Phase 3 – Serverless Transaction Flow & Bot Confirmation
|
|
149
|
+
|
|
150
|
+
- **3.1. Create transaction (serverless route)**
|
|
151
|
+
- Add `POST /api/tx/create`:
|
|
152
|
+
- Auth:
|
|
153
|
+
- From Mini App: validate `initData`, resolve `telegram_username`.
|
|
154
|
+
- From web/mobile: require a session or signed JWT containing `telegram_username` from Telegram login.
|
|
155
|
+
- Validate payload (action, amount, destination).
|
|
156
|
+
- Insert into `pending_transactions` with status `pending`.
|
|
157
|
+
- Use bot token to call `sendMessage` with:
|
|
158
|
+
- Text summary.
|
|
159
|
+
- Inline `web_app` button pointing to `https://t.me/<bot_username>?startapp=tx_<id>`.
|
|
160
|
+
- Return `{ id }` to caller for polling.
|
|
161
|
+
|
|
162
|
+
- **3.2. Confirmation page in Mini App**
|
|
163
|
+
- Implement a `tx/[id]`-like route in the Mini App (or use `start_param` parsing on the main screen) that:
|
|
164
|
+
- Reads `start_param` → extracts `<id>`.
|
|
165
|
+
- Calls `GET /api/tx/<id>`:
|
|
166
|
+
- Validates `initData`, ensures tx belongs to `telegram_username`.
|
|
167
|
+
- Returns tx summary (read-only).
|
|
168
|
+
- UI:
|
|
169
|
+
- Shows:
|
|
170
|
+
- Asset, amount, from / to addresses, network, estimated fee.
|
|
171
|
+
- A big, unambiguous **“Confirm”** button and a **“Reject”** button.
|
|
172
|
+
|
|
173
|
+
- **3.3. Local signing & completion**
|
|
174
|
+
- On **Confirm**:
|
|
175
|
+
- Mini App:
|
|
176
|
+
- Reconstructs the on-chain transaction from the payload and `wallet_address`.
|
|
177
|
+
- Signs it with the wallet key derived from mnemonic / master key in `SecureStorage`.
|
|
178
|
+
- Sends `POST /api/tx/<id>/complete` with:
|
|
179
|
+
- `id`
|
|
180
|
+
- `signedTx` (or `txHash` if client broadcasts).
|
|
181
|
+
- `decision: 'confirmed'`.
|
|
182
|
+
- `POST /api/tx/<id>/complete`:
|
|
183
|
+
- Validates `initData` and ownership.
|
|
184
|
+
- Verifies tx is still `pending`.
|
|
185
|
+
- Option A (backend broadcasting):
|
|
186
|
+
- Broadcast `signedTx` to RPC endpoint.
|
|
187
|
+
- On success/failure, update `status` accordingly and store `tx_hash`.
|
|
188
|
+
- Option B (client broadcasting):
|
|
189
|
+
- Trust `txHash` and mark as `confirmed`, or perform lightweight verification.
|
|
190
|
+
- Returns final status to Mini App.
|
|
191
|
+
|
|
192
|
+
- **3.4. Rejection path**
|
|
193
|
+
- On **Reject**:
|
|
194
|
+
- Mini App calls `POST /api/tx/<id>/complete` with `decision: 'rejected'`.
|
|
195
|
+
- Backend sets status `rejected`.
|
|
196
|
+
|
|
197
|
+
- **3.5. Client status updating**
|
|
198
|
+
- Any client that initiated the tx (Mini App, web, mobile app):
|
|
199
|
+
- Polls `GET /api/tx/<id>` until `status !== 'pending'`.
|
|
200
|
+
- Or uses lightweight WebSocket/SSE if desired.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Phase 4 – Hardening & Observability
|
|
205
|
+
|
|
206
|
+
- **4.1. Logging & audit**
|
|
207
|
+
- Add structured logging in all API routes:
|
|
208
|
+
- User identity (`telegram_username`), tx id, IP, user agent.
|
|
209
|
+
- Consider a `tx_history` view for user self-audits.
|
|
210
|
+
|
|
211
|
+
- **4.2. Rate limiting & abuse protection**
|
|
212
|
+
- Add rate limiting (IP + username) on:
|
|
213
|
+
- `/api/tx/create`
|
|
214
|
+
- `/api/login/telegram`
|
|
215
|
+
- Consider CAPTCHA or additional friction on spammy accounts.
|
|
216
|
+
|
|
217
|
+
- **4.3. Secrets & config**
|
|
218
|
+
- Store:
|
|
219
|
+
- Bot token, DB URL, RPC URLs, etc. in Vercel environment variables.
|
|
220
|
+
- Never log full mnemonics or keys; ensure any debug logging never prints sensitive values.
|
|
221
|
+
|
|
222
|
+
- **4.4. UX safety rails**
|
|
223
|
+
- On confirmation pages (Mini App & web):
|
|
224
|
+
- Highlight destination address and allow user to copy it.
|
|
225
|
+
- Show human-readable asset names & verify network.
|
|
226
|
+
- For large amounts, add extra confirmation step or warning.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Phase 5 – Optional Enhancements
|
|
231
|
+
|
|
232
|
+
- **5.1. Advanced local wallets (non-default)**
|
|
233
|
+
- In the mobile app and/or web app, optionally add:
|
|
234
|
+
- “Import mnemonic to this device” flow (explicit, with big warnings).
|
|
235
|
+
- Keep Telegram-first as the recommended path in docs and UI.
|
|
236
|
+
|
|
237
|
+
- **5.2. Multi-device / guardian support (future)**
|
|
238
|
+
- Extend smart contract / wallet to support multiple keys or social recovery.
|
|
239
|
+
- Use Telegram as one guardian channel among others.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
This plan should be implemented iteratively: Phase 1 (Mini App wallet), Phase 2 (mobile login shell), Phase 3 (serverless tx + confirmations), then hardening and enhancements. Each step can be validated independently (unit tests on API routes, manual testing in TMA, Expo mobile, and web).
|
|
244
|
+
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# Security Model: Telegram-First Wallet
|
|
2
|
+
|
|
3
|
+
## Goals
|
|
4
|
+
|
|
5
|
+
- Create wallets inside the Telegram Mini App.
|
|
6
|
+
- Let users access the **same wallet** from:
|
|
7
|
+
- Telegram on any device.
|
|
8
|
+
- Other platforms (web / desktop / native) via **Login with Telegram**.
|
|
9
|
+
- Keep custody with the **user** (mnemonic as ultimate root of trust), while using Telegram features to improve UX.
|
|
10
|
+
|
|
11
|
+
This document describes the current high-level design; it is not a formal audit.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Key Concepts & Storage
|
|
16
|
+
|
|
17
|
+
**Key terms**
|
|
18
|
+
|
|
19
|
+
- **Mnemonic (seed phrase)**: Ultimate secret that controls the wallet. If lost, funds are lost; if leaked, funds are at risk.
|
|
20
|
+
- **Wallet master key**: Device-specific key derived from the mnemonic and stored only on that device.
|
|
21
|
+
- **Wallet seed cipher**: Encrypted blob that contains the wallet seed (or a seed-derived secret), usable only together with the wallet master key.
|
|
22
|
+
- **Telegram CloudStorage**: Per-user, per-bot key–value store synced via Telegram servers. Suitable for non-secret data or ciphertext.
|
|
23
|
+
- **Telegram SecureStorage**: Per-device secure storage, backed by iOS Keychain / Android Keystore, intended for small sensitive values like tokens and keys (see [Mini Apps docs](https://core.telegram.org/bots/webapps#securestorage)).
|
|
24
|
+
|
|
25
|
+
We **never store raw mnemonics** on our backend or in Telegram CloudStorage.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## I. Wallet Creation in Telegram
|
|
30
|
+
|
|
31
|
+
Flow when a user creates a wallet for the first time in the Telegram Mini App on a device:
|
|
32
|
+
|
|
33
|
+
1. **Generate mnemonic on the device**
|
|
34
|
+
- The Mini App generates a new mnemonic locally (client-side).
|
|
35
|
+
- The user is shown the mnemonic once and asked to write it down for lifelong backup.
|
|
36
|
+
|
|
37
|
+
2. **Derive wallet master key (device-local)**
|
|
38
|
+
- From the mnemonic, the app derives a **wallet master key** (e.g. via a BIP-style KDF / HKDF).
|
|
39
|
+
- This master key is stored **only** in Telegram `SecureStorage` on that device.
|
|
40
|
+
- Because `SecureStorage` is backed by **Keychain / Keystore**, the key is:
|
|
41
|
+
- Encrypted at rest.
|
|
42
|
+
- Bound to this device + Telegram app.
|
|
43
|
+
|
|
44
|
+
3. **Create and store wallet seed cipher (cloud)**
|
|
45
|
+
- The app creates a **wallet seed cipher**:
|
|
46
|
+
- `seed_cipher = Encrypt(wallet_seed_or_root, wallet_master_key)`.
|
|
47
|
+
- `seed_cipher` is stored in Telegram `CloudStorage` under this bot for this user.
|
|
48
|
+
- CloudStorage contains **only ciphertext**, never raw seed or keys.
|
|
49
|
+
|
|
50
|
+
4. **Persist wallet mapping in our backend**
|
|
51
|
+
- Our backend stores a record like:
|
|
52
|
+
- `telegram_username` (Telegram username, treated as unique in our system),
|
|
53
|
+
- `wallet_address` (public address),
|
|
54
|
+
- metadata (creation time, network, etc.).
|
|
55
|
+
- No mnemonics or master keys are saved server-side.
|
|
56
|
+
|
|
57
|
+
**Properties**
|
|
58
|
+
|
|
59
|
+
- The **first Telegram device** has everything needed to use the wallet:
|
|
60
|
+
- Master key in `SecureStorage`.
|
|
61
|
+
- Seed cipher in `CloudStorage`.
|
|
62
|
+
- If the app is reinstalled on the **same device**, we can:
|
|
63
|
+
- Recover the master key from `SecureStorage` (if Telegram restores it).
|
|
64
|
+
- Decrypt the seed cipher for a smooth UX without re-entering the mnemonic.
|
|
65
|
+
- If `SecureStorage` is wiped, the user must re-enter the mnemonic.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## II. New Telegram Device Authorization
|
|
70
|
+
|
|
71
|
+
When the same user opens the Mini App on **another Telegram client** (new phone/tablet):
|
|
72
|
+
|
|
73
|
+
1. **Detect existing wallet**
|
|
74
|
+
- Using `initData` / backend lookup, we see that this `telegram_username` already owns at least one `wallet_address`.
|
|
75
|
+
|
|
76
|
+
2. **Check device SecureStorage**
|
|
77
|
+
- On this **new device**, `SecureStorage` is empty for our bot (no wallet master key yet).
|
|
78
|
+
- We may still see the `seed_cipher` in `CloudStorage` (it is synced across user devices), but without a master key it is useless.
|
|
79
|
+
|
|
80
|
+
3. **Ask user for mnemonic to authorize this device**
|
|
81
|
+
- The Mini App prompts the user to enter their mnemonic.
|
|
82
|
+
- From the mnemonic we derive a **new device-specific wallet master key** and store it in this device’s `SecureStorage`.
|
|
83
|
+
- Optionally, we re-encrypt and update the `seed_cipher` for this device; but the canonical root of trust remains the mnemonic.
|
|
84
|
+
|
|
85
|
+
**Result**
|
|
86
|
+
|
|
87
|
+
- Each Telegram device gains access only after the user proves knowledge of the mnemonic once.
|
|
88
|
+
- Loss of a device does **not** affect other devices, as long as the mnemonic is safe.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## III. Other Platforms (Outside Telegram)
|
|
93
|
+
|
|
94
|
+
For platforms outside Telegram (web, desktop app, native mobile app not running inside Telegram), we:
|
|
95
|
+
|
|
96
|
+
1. **Authenticate via Telegram**
|
|
97
|
+
- Use **Telegram Login for Websites** (see [login widget docs](https://core.telegram.org/widgets/login)) in a browser or embedded WebView.
|
|
98
|
+
- The login widget:
|
|
99
|
+
- Shows a Telegram-branded authorization UI where the user confirms sharing their Telegram identity with our site.
|
|
100
|
+
- After success, returns a signed payload containing `id`, `first_name`, `last_name`, `username`, `photo_url`, `auth_date`, and `hash`.
|
|
101
|
+
- On our backend we verify the `hash` using HMAC-SHA-256 with the SHA-256 of the bot’s token as a key, as described in the official docs.
|
|
102
|
+
- This works on:
|
|
103
|
+
- **Desktop browsers** (Chrome, Firefox, Safari, Edge, …),
|
|
104
|
+
- **Mobile browsers** on **iOS and Android**,
|
|
105
|
+
- In-app WebViews (e.g. inside a native app’s web login screen).
|
|
106
|
+
|
|
107
|
+
> For pure native iOS/Android apps, we typically embed a small web login page (with the widget) or open the system browser, then pass the verified Telegram identity back into the app.
|
|
108
|
+
|
|
109
|
+
2. **Lookup existing wallet**
|
|
110
|
+
- Once Telegram login succeeds, we resolve `telegram_username` in our DB.
|
|
111
|
+
- If there is an associated `wallet_address`, we know this user already owns a wallet.
|
|
112
|
+
|
|
113
|
+
3. **Authorize the device with the mnemonic**
|
|
114
|
+
- Because we are **outside Telegram**, we do not have Telegram’s `SecureStorage`.
|
|
115
|
+
- We therefore ask the user to **enter the mnemonic** to authorize this new platform.
|
|
116
|
+
- The app derives a **local wallet master key** from the mnemonic and stores it using the platform’s secure storage:
|
|
117
|
+
- iOS: Keychain
|
|
118
|
+
- Android: Keystore
|
|
119
|
+
- Desktop: DPAPI / Keychain / Keyring, depending on OS
|
|
120
|
+
- Web: WebCrypto + IndexedDB (with the usual caveats around user clearing storage).
|
|
121
|
+
|
|
122
|
+
**Result**
|
|
123
|
+
|
|
124
|
+
- Telegram login is used purely as an **identity layer** (“who is this user?”).
|
|
125
|
+
- The **mnemonic** is still required to authorize a completely new platform.
|
|
126
|
+
- Our backend never receives the raw mnemonic; only derived public keys / addresses.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## IV. Android / iOS (Single App, Telegram‑Centric Flow)
|
|
131
|
+
|
|
132
|
+
We ship **one app** (the current `./app` Expo app) to iOS/Android stores. On mobile, the app acts as a shell that:
|
|
133
|
+
|
|
134
|
+
- Explains why wallet creation happens in Telegram.
|
|
135
|
+
- Sends the user into the Telegram Mini App to actually create the wallet.
|
|
136
|
+
- Then uses **Telegram Login for Websites** + our backend to recognize the user and their wallet.
|
|
137
|
+
|
|
138
|
+
### Database: user identification (Telegram username–centric)
|
|
139
|
+
|
|
140
|
+
In the backend we maintain a `users` table (or equivalent) with at least:
|
|
141
|
+
|
|
142
|
+
- `telegram_username` – Telegram username, treated as unique in our system.
|
|
143
|
+
- `wallet_address` – current wallet address owned by this username.
|
|
144
|
+
|
|
145
|
+
The mobile app never needs to store the mnemonic or keys; it only needs the `telegram_username` and `wallet_address` retrieved from the backend after Telegram login.
|
|
146
|
+
|
|
147
|
+
### A. New user on iOS/Android (no wallet yet)
|
|
148
|
+
|
|
149
|
+
1. **App start → “Log in with Telegram” screen**
|
|
150
|
+
- Shown when there is no linked `telegram_username` in local app storage.
|
|
151
|
+
- Content:
|
|
152
|
+
- Title: “Create your wallet in Telegram”.
|
|
153
|
+
- Short text summarizing benefits:
|
|
154
|
+
- “Wallets are created **inside Telegram**, we never see your seed phrase.”
|
|
155
|
+
- “Your keys are stored using Telegram **SecureStorage + CloudStorage** on your devices.”
|
|
156
|
+
- “You can access the same wallet from Telegram, web, and this app.”
|
|
157
|
+
- UI:
|
|
158
|
+
- Primary button: **“Open Telegram to create wallet”**.
|
|
159
|
+
- Secondary button (dimmed / smaller): **“I already created my wallet in Telegram”** (goes to login widget, see flow B).
|
|
160
|
+
- Action on primary:
|
|
161
|
+
- Deep link to Mini App, e.g. `https://t.me/<bot_username>?startapp=wallet_onboarding`.
|
|
162
|
+
|
|
163
|
+
2. **Telegram Mini App: wallet creation (same as section I)**
|
|
164
|
+
- Generate mnemonic, show/confirm it.
|
|
165
|
+
- Derive wallet master key → store in `SecureStorage`.
|
|
166
|
+
- Encrypt wallet seed → store cipher in `CloudStorage`.
|
|
167
|
+
- Call backend `register_wallet(telegram_username, wallet_address)` which:
|
|
168
|
+
- Creates a new `users` row.
|
|
169
|
+
- Stores `telegram_username`, `wallet_address`.
|
|
170
|
+
- Show a completion screen:
|
|
171
|
+
- “Your wallet is ready in Telegram.”
|
|
172
|
+
- Instruction: “Return to the app and tap ‘I already created my wallet’ to connect.”
|
|
173
|
+
|
|
174
|
+
3. **Back in iOS/Android app → “Log in with Telegram” (Telegram login widget)**
|
|
175
|
+
- User returns to the app and taps **“I already created my wallet in Telegram”** (or simply “Log in with Telegram”).
|
|
176
|
+
- App opens an embedded WebView or browser page with **Telegram Login for Websites**:
|
|
177
|
+
- Widget asks the user to confirm sharing their Telegram identity.
|
|
178
|
+
- After success, backend receives a signed payload and validates it as in section III.
|
|
179
|
+
- Backend extracts `username` from the payload and looks up `telegram_username` in `users`:
|
|
180
|
+
- If found, returns `{ telegram_username, wallet_address, ... }` to the app.
|
|
181
|
+
- If not found (edge case: user logged in before creating wallet), the app can:
|
|
182
|
+
- Show “No wallet yet, please create it in Telegram first” and show the **Open Telegram** button again.
|
|
183
|
+
|
|
184
|
+
4. **App state after linking**
|
|
185
|
+
- The app stores `telegram_username` and `wallet_address` in its local storage.
|
|
186
|
+
- It can now:
|
|
187
|
+
- Display balances / history via backend or blockchain APIs.
|
|
188
|
+
- For signing, either:
|
|
189
|
+
- Redirect back to Telegram Mini App on an action (“Sign in Telegram”), or
|
|
190
|
+
- In a future advanced flow, allow the user to import mnemonic locally (explicit, non‑default).
|
|
191
|
+
|
|
192
|
+
### B. Existing Telegram wallet user installing iOS/Android app
|
|
193
|
+
|
|
194
|
+
For a user who already has a Telegram wallet (created earlier in the Mini App):
|
|
195
|
+
|
|
196
|
+
1. **App start → same “Log in with Telegram” screen**
|
|
197
|
+
- The screen is identical, but the text emphasizes:
|
|
198
|
+
- “If you already created your wallet in Telegram, just log in below.”
|
|
199
|
+
- Action:
|
|
200
|
+
- User taps **“I already created my wallet in Telegram”** / **“Log in with Telegram”**.
|
|
201
|
+
|
|
202
|
+
2. **Telegram Login for Websites**
|
|
203
|
+
- Same widget flow as in A.3.
|
|
204
|
+
- Backend verifies the payload and looks up `telegram_username` in `users`:
|
|
205
|
+
- If a row exists → return `{ telegram_username, wallet_address }` to the app.
|
|
206
|
+
- If no row exists → the app suggests:
|
|
207
|
+
- “We don’t see a wallet yet. Please open Telegram to create one.” and shows the **Open Telegram to create wallet** button.
|
|
208
|
+
|
|
209
|
+
3. **After login**
|
|
210
|
+
- The app saves `telegram_username` + `wallet_address` locally and shows the wallet UI.
|
|
211
|
+
- No mnemonic is ever handled by the app in this default flow.
|
|
212
|
+
|
|
213
|
+
**Key points of this model**
|
|
214
|
+
|
|
215
|
+
- There is **one app** (`./app`), not a separate companion; mobile just has a Telegram‑centric onboarding path.
|
|
216
|
+
- All wallet creation and key material remain in the Telegram Mini App and its SecureStorage/CloudStorage environment.
|
|
217
|
+
- The iOS/Android app uses:
|
|
218
|
+
- **Telegram Login for Websites** to learn “who is this user?” (via `username`),
|
|
219
|
+
- The backend’s `users` table (`telegram_username`, `wallet_address`) to link that identity to a wallet.
|
|
220
|
+
- Users who don’t want to connect Telegram can only use future “local‑only” features if we add them explicitly; the default path is Telegram‑first.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## V. Serverless Transaction Flow & Bot‑Based Confirmation
|
|
225
|
+
|
|
226
|
+
We assume a **serverless backend** (e.g. Vercel / Cloudflare / Lambda functions) with:
|
|
227
|
+
|
|
228
|
+
- Stateless HTTP handlers (API routes).
|
|
229
|
+
- A persistent datastore (serverless Postgres / KV / Dynamo, etc.) for:
|
|
230
|
+
- `users` (`telegram_username`, `wallet_address`, …).
|
|
231
|
+
- `pending_transactions` (id, telegram_username, payload, status, timestamps).
|
|
232
|
+
|
|
233
|
+
All **signing** happens on the client side (Telegram Mini App or other wallet environment); serverless functions never hold private keys.
|
|
234
|
+
|
|
235
|
+
### 1. Initiating a transaction (any client)
|
|
236
|
+
|
|
237
|
+
From any frontend (Telegram Mini App, web, iOS/Android app):
|
|
238
|
+
|
|
239
|
+
1. Client sends a request to a serverless endpoint, e.g. `POST /api/tx/create`:
|
|
240
|
+
- Body includes:
|
|
241
|
+
- `telegram_username` (or derived from Telegram auth),
|
|
242
|
+
- transaction intent (action type, amount, asset, destination, etc.).
|
|
243
|
+
2. Serverless handler:
|
|
244
|
+
- Validates the request and user identity.
|
|
245
|
+
- Creates a `pending_transactions` row with:
|
|
246
|
+
- `id` (e.g. UUID or short code),
|
|
247
|
+
- `telegram_username`,
|
|
248
|
+
- serialized transaction payload (what needs to be signed),
|
|
249
|
+
- status = `pending`.
|
|
250
|
+
- Uses the **Telegram Bot API** to send a push message to the user:
|
|
251
|
+
- “New action requires confirmation: <summary>”.
|
|
252
|
+
- Inline button: **“Review & confirm”** linking to:
|
|
253
|
+
- Recommended: Mini App deep link, e.g.\
|
|
254
|
+
`https://t.me/<bot_username>?startapp=tx_<id>`
|
|
255
|
+
- Optionally, a web URL, e.g.\
|
|
256
|
+
`https://app.hyperlinks.space/tx/<id>`.
|
|
257
|
+
|
|
258
|
+
### 2. Confirmation page (Telegram Mini App)
|
|
259
|
+
|
|
260
|
+
When the user taps the button in the bot message and opens the Mini App:
|
|
261
|
+
|
|
262
|
+
1. The Mini App receives `start_param = tx_<id>` via `initData`.
|
|
263
|
+
2. It calls a serverless endpoint, e.g. `GET /api/tx/<id>`:
|
|
264
|
+
- Backend verifies the request using `initData`/`hash` and checks that:
|
|
265
|
+
- `pending_transactions.id` exists,
|
|
266
|
+
- `telegram_username` from DB matches the Mini App user,
|
|
267
|
+
- status is `pending`.
|
|
268
|
+
- Backend returns the transaction details (read‑only).
|
|
269
|
+
3. Mini App shows a **confirmation UI**:
|
|
270
|
+
- Clear summary: amounts, assets, destination, fees, network.
|
|
271
|
+
- Buttons: **Confirm** / **Reject**.
|
|
272
|
+
|
|
273
|
+
### 3. Signing & broadcasting (inside Telegram)
|
|
274
|
+
|
|
275
|
+
On **Confirm** from the Mini App:
|
|
276
|
+
|
|
277
|
+
1. Mini App reconstructs/derives the transaction to be signed using:
|
|
278
|
+
- The locally available wallet (seed/master key in `SecureStorage`).
|
|
279
|
+
- The payload from `pending_transactions`.
|
|
280
|
+
2. Mini App signs the transaction **locally** using the wallet key.
|
|
281
|
+
3. Mini App sends a request to a serverless endpoint, e.g. `POST /api/tx/<id>/complete` with:
|
|
282
|
+
- `id`,
|
|
283
|
+
- signed transaction payload (or only the resulting transaction hash if the client broadcasts itself),
|
|
284
|
+
- confirmation that user accepted.
|
|
285
|
+
4. Serverless handler:
|
|
286
|
+
- Verifies that the caller is the right `telegram_username` and that tx is still `pending`.
|
|
287
|
+
- Either:
|
|
288
|
+
- Broadcasts the signed transaction to the chain (if backend has RPC access and broadcasting doesn’t leak secrets), **or**
|
|
289
|
+
- Simply records the fact that this transaction was confirmed and uses a separate service / worker to broadcast.
|
|
290
|
+
- Updates `pending_transactions.status` to `confirmed` (or `failed` with reason).
|
|
291
|
+
|
|
292
|
+
The originating client (web / mobile app) can poll or subscribe for status changes on `pending_transactions` to reflect completion.
|
|
293
|
+
|
|
294
|
+
### 4. Optional: web‑only confirmation page
|
|
295
|
+
|
|
296
|
+
For users who click a **web URL** from the bot instead of the Mini App:
|
|
297
|
+
|
|
298
|
+
- The confirmation page:
|
|
299
|
+
- Uses **Telegram Login for Websites** to authenticate the user (retrieve `username`).
|
|
300
|
+
- Loads the `pending_transactions` row by `id` + `telegram_username`.
|
|
301
|
+
- Shows the same confirmation UI.
|
|
302
|
+
- For signing, we recommend **redirecting back to Telegram** for actual key usage:
|
|
303
|
+
- On **Confirm**, the web page can:
|
|
304
|
+
- Either deep‑link into the Mini App with the same `tx_<id>`, or
|
|
305
|
+
- Ask the user to enter the mnemonic or connect an external wallet (advanced, non‑default).
|
|
306
|
+
- This keeps the **self‑custodial key** anchored in the Mini App by default, while still allowing purely web‑based flows where the user explicitly opts into entering their mnemonic or linking another wallet.
|
|
307
|
+
|
|
308
|
+
### Serverless guarantees
|
|
309
|
+
|
|
310
|
+
- All backend logic is stateless across requests; long‑lived data lives in `users` and `pending_transactions`.
|
|
311
|
+
- No private keys or mnemonics are ever stored or derived in serverless functions.
|
|
312
|
+
- Bot pushes and confirmation flows are coordinated exclusively via:
|
|
313
|
+
- Telegram Bot API (for notifications),
|
|
314
|
+
- Telegram Mini App (for secure signing with SecureStorage),
|
|
315
|
+
- Telegram Login (for identity on web / mobile).
|
|
316
|
+
|
|
317
|
+
This model keeps transaction approvals **user‑driven and key‑local** (inside Telegram or another explicit wallet) while still fitting neatly into a serverless architecture.
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Security Properties
|
|
322
|
+
|
|
323
|
+
- **Self-custody:**
|
|
324
|
+
- The mnemonic is the **only ultimate key**; if the user keeps it offline and safe, they retain full control over funds.
|
|
325
|
+
- Neither our backend nor Telegram can unilaterally move funds without the mnemonic / keys.
|
|
326
|
+
|
|
327
|
+
- **Device-local keys:**
|
|
328
|
+
- Each device has its own **wallet master key** stored in that device’s secure storage (Telegram SecureStorage or OS keystore).
|
|
329
|
+
- Compromise of one device does **not** automatically compromise others.
|
|
330
|
+
|
|
331
|
+
- **Cloud data is ciphertext only:**
|
|
332
|
+
- `Wallet Seed Cipher` in CloudStorage is encrypted with a master key that lives only in secure storage on a device.
|
|
333
|
+
- An attacker with only CloudStorage access cannot derive the mnemonic.
|
|
334
|
+
|
|
335
|
+
- **Cross-platform restore requires mnemonic:**
|
|
336
|
+
- Any **new environment** (new Telegram device with empty SecureStorage or any non-Telegram platform) requires the mnemonic once.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Limitations & Notes
|
|
341
|
+
|
|
342
|
+
- If the **mnemonic is lost**, there is no recovery (by design) – it is the self-custodial root.
|
|
343
|
+
- If a device with a master key is compromised, an attacker can act as the owner from that device until the user moves funds to a new wallet.
|
|
344
|
+
- Telegram `SecureStorage` is documented for **iOS and Android**; behavior on other Telegram clients may differ.
|
|
345
|
+
- Telegram Login for Websites is an **authentication mechanism only** – it does not give access to keys or the mnemonic itself, and cannot replace the mnemonic for wallet authorization.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Raw timing estimate
|
|
2
|
+
|
|
3
|
+
**Purpose:** Rough “time till app finish” and **MVP launch** based on commit history, plans, and the front app.
|
|
4
|
+
|
|
5
|
+
**Important:** The app will not be sent to platforms (store/listing) before it is fully finished. So **MVP launch = full product launch**, and the realistic estimate is **3 months**.
|
|
6
|
+
|
|
7
|
+
## Transfer layout to `./app` (TypeScript) — build on new architecture
|
|
8
|
+
|
|
9
|
+
The goal is **not** to finish the Flutter app in `front/`. The **Flutter** app in `front/` is the **reference layout** (web pages, flows, structure). The work is to **transfer that layout and flows into `./app` in TypeScript** and make everything work there, with **security plan compliance** (see `docs/security_plan.md`). The production Mini App is the TS app in `./app` (Expo/React), backed by the same repo’s API and DB.
|
|
10
|
+
|
|
11
|
+
### Pages to implement in `./app` (TS) — from `front/` reference
|
|
12
|
+
|
|
13
|
+
- **Bootstrap** – initData auth, config from API, wallet warm-up.
|
|
14
|
+
- **Main** – home / hub after bootstrap.
|
|
15
|
+
- **Send** – send flow (security plan: pending tx, confirmations).
|
|
16
|
+
- **Swap** – swap flow (rate state, rotation, etc. from root plan).
|
|
17
|
+
- **Wallets** – list/create/manage; wallet creation and nickname (security plan: mnemonic flow, device auth, wallet registration).
|
|
18
|
+
- **Apps** – apps design, brand book alignment.
|
|
19
|
+
- **AI** – AI & search bar; response formatting; scrolling fix; wired to `app` AI routes.
|
|
20
|
+
- **Get** – get flow.
|
|
21
|
+
- **Trade** – trade page.
|
|
22
|
+
- **Creators** – creators content.
|
|
23
|
+
- **Mnemonics** – mnemonic display/backup (security plan).
|
|
24
|
+
- **Wallet panel** – wallet panel page.
|
|
25
|
+
|
|
26
|
+
### Services / wiring in `./app` (TS)
|
|
27
|
+
|
|
28
|
+
| Concern | Role | Backend / compliance |
|
|
29
|
+
|--------|------|-----------------------|
|
|
30
|
+
| **Auth** | Telegram initData auth (e.g. app’s telegram/init endpoint). | initData validation and user upsert (Phase 0–1). |
|
|
31
|
+
| **AI** | Chat with AI via same-origin `/api/ai` (or app’s AI route). | Already in `app`; ensure config, keys, and error handling in prod. |
|
|
32
|
+
| **Wallet** | Mnemonic generation, storage, key derivation (client-side). | Security plan: SecureStorage/CloudStorage, wallet registration (`POST /api/wallet/register`), device auth flow; optional TonConnect later. |
|
|
33
|
+
|
|
34
|
+
### API surface (in `./app`)
|
|
35
|
+
|
|
36
|
+
- **`/api/telegram`** (or init) – initData validation, user upsert.
|
|
37
|
+
- **`/api/ai`** – AI proxy; used by the TS app.
|
|
38
|
+
|
|
39
|
+
All of the above must work end-to-end in the TS app and stay within the security model (initData-only auth, no raw secrets to server, wallet registration and pending tx where applicable).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Short and Medium term backlogs
|
|
44
|
+
|
|
45
|
+
- **`app/short_term_backlog.md`** (3 items): Response formatting, app theme, AI & search bar.
|
|
46
|
+
- **Root `medium_term_backlog.md`** (backlog): Header indent bug, rotation on swap, edit-interval healthcheck, ticker link, scrolling in AI widget, bot parts isolation, ld timeout, “AI bd”, hovers, languages, favicon, wallet creation & nickname, jetton lockup, theme in Chrome, “Bd”, wallet creation, apps design, plan users BD for search, brand book, fixes, starting rewards, feed item types, PAY BY QR, swap long rate state, swaps, tokens.
|
|
47
|
+
|
|
48
|
+
**Security:** All features above are delivered **with security plan compliance** (Phase 0–2: initData validation, wallet creation and registration, device auth, pending transactions, TonConnect if in scope, etc.). No “MVP without security”; the launch build is compliant.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Time estimate
|
|
53
|
+
|
|
54
|
+
Completion order and stages:
|
|
55
|
+
|
|
56
|
+
| Stage | Scope | Estimate | Notes |
|
|
57
|
+
|-------|--------|----------|--------|
|
|
58
|
+
| **1** | **Security plan implementation** | **~3 weeks** | Phase 0 (validation, DB), Phase 1 (wallet creation, device auth, register), Phase 2 (pending tx, confirmations). |
|
|
59
|
+
| **2** | **App (TS) – pages & UX** | **~3 weeks** | Transfer layout from `front/` and implement all pages in `./app` (send, swap, wallets, apps, AI, get, trade, creators, mnemonics, wallet panel); layout and navigation solid. |
|
|
60
|
+
| **3** | **App (TS) – services & wiring** | **~3 weeks** | Auth, AI, and wallet flows in `./app`; backend alignment; errors and edge cases. |
|
|
61
|
+
| **4** | **Integration, testing, finishing** | **~3 weeks** | E2E, platform checks, store/listing readiness, app/plan and root plan items (formatting, theme, bugs, features). |
|
|
62
|
+
|
|
63
|
+
**MVP launch (full finish, platform-ready):** **~3 months** (12 weeks).
|