Skip to main content

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), plus app/binder, app/market, app/quests, app/settings, and the engine route app/(tabs)/locker-room/games/[gameKey].
  • Feature logic: extracted hooks such as use-wallet-screen.ts and use-shop-screen.ts.
  • Shared contexts: user, collectibles, accessibility, and UI visibility/state controls.
  • Styles: dedicated *.styles.ts files. Do not put StyleSheet.create inside 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, and GET /api/teams/{id}/roster.
  • Game Engine calls use lib/api/games-engine-api.ts through useGamesEngineApi(), not the shared useApi() 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.tsx and captureDeepLinkUrl parse it, takePendingMobileSessionToken() stashes it in memory (not MMKV), and consumePendingMobileSessionToken redeems it at POST /api/mobile/exchange.
  • Android App Links cover api.d-sports.org mobile callbacks and app.d-sports.org paths (/locker-room, /profile, /market, /quests, /binder, /leaderboard, /rate). iOS also claims applinks: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-key is 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.