Mobile Development
Status of the Vezta mobile app
A native Vezta mobile app is planned but not yet implemented. This page describes the current state and the planned stack.
Current Status
- Designs -- Complete (
plans/mobile/). 5-tab nav, bottom-sheet trading, Lite/Pro toggle, 61 screens, 29 reusable components, 8 phases. - Implementation -- Not started in code. The
vezta-mobile/directory does not yet exist in the repository. - Backend support -- Already in place:
push-notificationmodule,app-versionmodule,device-tokenendpoints, and aDeviceTokenPrisma model are wired up so the mobile client can plug in immediately when implementation begins. - Telegram-first interim -- The
@vezta_botinteractive trading bot (plans/vezta-bot/) is being built first as a faster path to a "mobile-feeling" experience while the native app is in flight. The signal bot@vezta_signal_botis already shipping insider alerts to@vezta_signals.
Planned Stack
| Technology | Version | Purpose |
|---|---|---|
| Expo SDK | 55 | Managed workflow with EAS Build |
| React Native | 0.83 | Cross-platform mobile rendering |
| Expo Router | -- | File-based routing with typed routes |
| NativeWind | v4 | Tailwind CSS for React Native via className prop |
| React Native Reanimated | v4 | High-performance animations |
| TanStack Query | v5 | Server state with offline persistence (AsyncStorage persister) |
| Zustand | -- | Local UI stores |
| Jotai | -- | WebSocket atom state |
| Socket.IO | v4 | Real-time data with AppState-aware connect/disconnect |
expo-secure-store | -- | Refresh-token storage (device secure enclave) |
expo-local-authentication | -- | Biometric auth (Face ID / Touch ID) |
expo-notifications | -- | Push notifications |
@gorhom/bottom-sheet | -- | Trading sheet and modal presentations |
expo-image | -- | Image rendering with caching |
expo-updates | -- | OTA updates |
| Jest + RNTL | -- | Unit testing |
Planned Navigation Structure
5-tab bottom navigation:
| Tab | Path | Screens |
|---|---|---|
| Home | (tabs)/home/ | Feed, trending, balance overview, notifications |
| Markets | (tabs)/markets/ | Browse, search, filter, [slug] market detail + trading sheet |
| Portfolio | (tabs)/portfolio/ | Positions, orders, watchlist, PnL analytics (auth required) |
| Social | (tabs)/social/ | Leaderboard, copy trade, wallet activity |
| More | (tabs)/more/ | Settings, rewards, events, AI signals, monitor, help |
Auth screens ((auth)/ group) display without the tab bar: login, welcome-back, access-key, biometric setup, onboarding, waitlist.
Code Sync from Web
When the mobile app starts development, several layers will be shared with vezta-fe and kept in sync manually:
| Shared Layer | Path | Sync Method |
|---|---|---|
| API types, schemas, hooks | lib/api/gen/ | Copy from vezta-fe after pnpm generate |
| Utilities | lib/utils.ts | Copy from vezta-fe |
| Constants | lib/constants.ts | Copy from vezta-fe |
| TypeScript interfaces | lib/types/ | Copy from vezta-fe |
| Trading helpers | lib/trading/ | Copy from vezta-fe |
Never hand-edit lib/api/gen/. After any backend API change, regenerate in vezta-fe with pnpm generate, then copy the output to vezta-mobile/lib/api/gen/.
Auth Plan
Mobile auth uses the same wallet-based + Google flow as the web. Key differences:
- Refresh tokens are stored in
expo-secure-store(not AsyncStorage). SecureStore uses the device's secure enclave. - Access tokens stay in-memory.
- The API client at
lib/api/client.tshandles automatic 401 refresh-and-retry.
Never use AsyncStorage for sensitive data (tokens, keys). SecureStore has a 2048-byte value limit, so only store tokens -- not large data blobs.
Planned Gotchas
When implementation starts:
- NativeWind v4 uses
className-- not thestyleprop for Tailwind classes - Reanimated v4 requires the babel plugin in
babel.config.js - Bottom sheet (
@gorhom/bottom-sheet) needsGestureHandlerRootViewas an ancestor - Expo Router typed routes require
experiments.typedRoutes: truein app config - Font loading must complete before rendering -- use
expo-splash-screento prevent flash - Always disconnect and reconnect WebSocket on AppState background/foreground transitions
- Decimal values from the API are strings -- parse with
parseFloat()before math - Use
expo-imageinstead of React Native's<Image>for better caching performance
Related
plans/mobile/-- 8-phase implementation plan with screen designsplans/vezta-bot/-- interactive Telegram trading bot (currently in development as a near-term mobile alternative)