App architecture
The native app is structured around Expo Router screens, feature-oriented components, shared hooks, and API modules. Screen files are JSX-only shells. State, effects, and handlers live in dedicated hooks.- Routing:
app/*with grouped routes for(tabs),(auth),(onboarding),(admin), plusapp/binder,app/market,app/quests,app/settings, and the engine routeapp/(tabs)/locker-room/games/[gameKey]. - Feature logic: extracted hooks such as
use-wallet-screen.tsanduse-shop-screen.ts. - Shared contexts: user, collectibles, accessibility, and UI visibility/state controls.
- Styles: dedicated
*.styles.tsfiles. Do not putStyleSheet.createinside screen files.
State and context boundaries
- Local/ephemeral UI state lives near feature hooks and components.
- Cross-screen state is managed with Zustand and persisted through MMKV.
- API responses can fall back to
lib/api/cache.ts(MMKV). - User/session-sensitive state is coordinated with backend auth and profile sync endpoints.
API client and retry behavior
- Game Center and locker-room lineups use
lib/api/events-api.ts,lib/api/locker-room-api.ts, andGET /api/teams/{id}/roster. - Game Engine calls use
lib/api/games-engine-api.tsthroughuseGamesEngineApi(), not the shareduseApi()bag. See Game Engine client. - All other network calls route through
lib/api/*modules. - Client wrappers handle auth token propagation, error normalization, and retry strategy.
- Quest, Fan Rep, reward, and team flows should consume backend eligibility as source of truth.
Auth and deep-link entry
- Clerk (
@clerk/expo) owns the session after login. - Login supports Google OAuth, Apple Sign In, email/password, and MFA (TOTP, SMS, or email code).
- Mobile OAuth can land a 128-char hex token in the URL fragment.
+native-intent.tsxandcaptureDeepLinkUrlparse it,takePendingMobileSessionToken()stashes it in memory (not MMKV), andconsumePendingMobileSessionTokenredeems it atPOST /api/mobile/exchange. - Android App Links cover
api.d-sports.orgmobile callbacks andapp.d-sports.orgpaths (/locker-room,/profile,/market,/quests,/binder,/leaderboard,/rate). iOS also claimsapplinks:app.d-sports.org.
Wallet signing
- Custodial wallets sign on the server via
POST /api/wallets/{address}/sign-transaction. - The client PIN-gates the flow. Do not sign with a locally exported private key for custodial sends.
POST /api/wallets/private-keyis deprecated on the API.
Platform-specific behavior
- iOS/Android platform differences are handled in native-specific components and runtime checks.
- iPad and tablets are supported (
supportsTablet). Orientation-aware layouts exist for tablets and foldables. Web-target support exists but mobile behavior is primary. - The app requires an Expo dev client. Expo Go cannot load MMKV, RevenueCat, or Filament.
- Haptics, modal controls, and animation handling are implemented with platform-safe fallbacks.
