Skip to main content

Overview

d-sports-engage-native (package name: engage-native) is the native mobile app for D-Sports. It mirrors the core PWA experience on iOS and Android: wallet, shop, leaderboard, locker room, and profile.
  • Run: bunx expo start — then press a for Android, i for iOS, or scan the QR code with Expo Go.
  • Version: 1.10.5
  • Bundle ID: com.dsports.wallet.beta (iOS and Android)

Tech stack

CategoryTechnology
FrameworkExpo 54, React Native 0.81, React 19
AuthClerk (@clerk/clerk-expo)
PaymentsRevenueCat (react-native-purchases)
Web3Thirdweb SDK
StateZustand 5 + React Context
StorageMMKV (synchronous persistence)
UILucide React Native
NavigationExpo Router 6 (file-based routing)
AnimationsReact Native Reanimated 4
MonitoringSentry (@sentry/react-native)
PackageBun

Features

  • Wallet — token balances, holdings, pack opening, crypto checkout (via PWA backend), PIN verification
  • Shop — collectibles, cart, coin bundles, crypto and fiat checkout
  • Leaderboard — rankings and filters
  • Locker room — social feed, teams, quests, daily games (Pick’Em, Spin Wheel, Guess the Player)
  • Profile — user profile, settings, and account management
  • Theme — dark/light mode (default dark)
  • PWA supportdisplay: standalone, responsive desktop layout (max 480 px), web hover states

Getting started

1

Install dependencies

bun install
2

Configure environment

Create a .env file in the project root with the following variables:
VariableDescription
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEYClerk publishable key
EXPO_PUBLIC_API_URLAPI backend URL (e.g. https://api.d-sports.org)
EXPO_PUBLIC_TW_CLIENT_IDThirdweb client ID
EXPO_PUBLIC_REVENUECAT_API_KEYRevenueCat API key
EXPO_PUBLIC_REVENUECAT_APPSTORE_IDRevenueCat App Store ID
EXPO_PUBLIC_REVENUECAT_ENTITLEMENTRevenueCat entitlement name
EXPO_PUBLIC_SUPABASE_URLSupabase project URL
EXPO_PUBLIC_SUPABASE_KEYSupabase publishable key
Only EXPO_PUBLIC_* variables are accessible at runtime in the Expo app.
3

Start the dev server

bunx expo start
Press a for Android, i for iOS, or scan the QR code with Expo Go.
4

Type-check

bun tsc --noEmit

Project structure

app/
├── (auth)/              # Login, signup, password reset, SSO callback
├── (onboarding)/        # New user onboarding flow
├── (tabs)/              # Main tab navigation (wallet, shop, leaderboard, locker room, profile)
├── settings/            # Settings pages with nested modals and tabs
└── _layout.tsx          # Root layout with providers and auth protection

components/
├── wallet/              # Wallet sub-components (TokenRow, HoldingRow, PackOpeningModal, etc.)
├── shop/                # Shop sub-components (CartModal, CryptoCheckoutModal, etc.)
├── locker-room/         # Locker room components (feed, quests, games, teams)
├── leaderboard/         # Leaderboard components
├── settings/            # Settings components, modals, and tabs
├── ui/                  # Reusable UI primitives (Button, TextField, WebHoverWrapper)
├── Icon/                # Icon wrapper using lucide-react-native
└── theme-provider.tsx   # Theme context (dark/light)

hooks/
├── use-wallet-screen.ts # All wallet state, effects, and handlers
├── use-shop-screen.ts   # All shop state, effects, and handlers
└── use-feed-section.ts  # Feed data and interaction logic

lib/
├── api/                 # API client modules (wallet, shop, user, quests, checkout, etc.)
├── revenuecat/          # RevenueCat in-app purchases provider
└── crypto/              # On-chain transaction helpers

context/                 # React Context providers (user, collectibles, navbar visibility)
services/                # Zustand store, MMKV storage adapter, core types
types/                   # TypeScript types (wallet, shop, checkout, API responses)
constants/               # Static data (tokens, coin bundles, locker room config)
theme/                   # Brand colors, spacing, typography tokens

Architecture

Screen pattern

Screen files under app/(tabs)/ contain only JSX. All state, effects, and handlers live in dedicated hooks:
  • hooks/use-wallet-screen.ts — wallet/token fetching, PIN verification, transaction handlers
  • hooks/use-shop-screen.ts — cart state, product queries, carousel auto-scroll, checkout logic
Sub-components are extracted into components/wallet/ and components/shop/ with barrel exports.

State management

  • Zustand store (services/store.ts) with MMKV persistence for theme, cart, and points
  • React Context providers for authentication (UserContext), collectibles (CollectiblesContext), and navbar visibility

API client layer

lib/api/client.ts is the base HTTP client with Clerk auth token injection. Domain-specific modules (wallet-api.ts, shop-api.ts, user-api.ts, quests-api.ts, leaderboard-api.ts, locker-room-api.ts, teams-api.ts, collectibles-api.ts, checkout-api.ts) are surfaced through a single useApi() hook from lib/api/index.ts. Responses are cached with MMKV via lib/api/cache.ts for offline-first fallback.

Payments

  • Fiat: RevenueCat handles Apple IAP (native), Google Play (native), and Stripe (web) via lib/revenuecat/provider.tsx
  • Crypto: Thirdweb SDK signs on-chain transactions against the PWA backend (POST /api/checkout/crypto and POST /api/checkout/crypto/verify). Supported chains: Arbitrum (default), Ethereum, Polygon.

Path alias

Use the @/* alias to import from the project root:
import { useUser } from "@/context/user-context";
import type { Token } from "@/types/wallet.types";

EAS builds and deployment

The app uses Expo Application Services (EAS) for native builds, OTA updates, and store submissions.

Build profiles

ProfilePurposeCommand
developmentDev client (simulator)bun run build:dev
previewInternal QA (APK/ad hoc)bun run build:preview
productionStore-readybun run build:prod

OTA updates

Push JS-only changes without a new store build:
bun run update --branch production --message "Fix: wallet balance display"
Build profileUpdate channelAudience
developmentdevelopmentDev builds
previewpreviewInternal testers
productionproductionApp Store users
OTA updates only work when the JS bundle is compatible with the installed native binary. If you add or change native modules, do a full build first and bump the version in app.json.

Store submission

bun run submit          # both platforms
bun run submit:ios      # iOS only
bun run submit:android  # Android only

Branding

TokenValue
Base background#0a0e1a
Accent gold#F5C842
Primary blue#4169E1
Default themeDark

Ecosystem overview

See how the native app fits with the PWA, site, and Mic’d Up.