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.

Tech stack

CategoryTechnology
FrameworkExpo 54, React Native 0.81, React 19
AuthClerk (Expo)
PaymentsRevenueCat (fiat: Apple IAP, Google Play, Stripe)
Web3Thirdweb SDK (crypto checkout)
StateZustand + MMKV persistence
NavigationExpo Router 6 (file-based routing)
UILucide React Native, Reanimated 4.1
PackageBun

Features

  • Wallet — Tokens, holdings, pack opening, crypto checkout (via PWA backend)
  • Shop — Collectibles, cart, coin bundles, checkout
  • Leaderboard — Rankings and filters
  • Locker room — Social feed and engagement
  • Profile — User profile and settings
  • Theme — Dark/light mode (default dark)
  • PWA-ready — Standalone display, responsive desktop layout, web hover states

Getting started

1

Install dependencies

bun install
2

Configure environment

Create a .env file with the following keys:
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY="your-clerk-key"
EXPO_PUBLIC_API_URL="https://api.d-sports.org"
EXPO_PUBLIC_TW_CLIENT_ID="your-thirdweb-client-id"
EXPO_PUBLIC_REVENUECAT_API_KEY="your-revenuecat-key"
3

Start development server

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

Build for devices (optional)

bun run build:dev  # EAS development build

Project structure

app/
├── (auth)/              # Login/signup screens
├── (onboarding)/        # New user onboarding flow
├── (tabs)/              # Main tab navigation
│   ├── wallet.tsx       # Wallet screen (JSX only—logic in hook)
│   ├── shop.tsx         # Shop screen (JSX only—logic in hook)
│   ├── leaderboard.tsx  # Leaderboard screen
│   ├── locker-room.tsx  # Social feed
│   └── profile.tsx      # User profile
├── settings/            # Settings pages with nested modals/tabs
└── _layout.tsx          # Root layout with providers + auth protection

components/
├── wallet/              # 9 extracted wallet sub-components
├── shop/                # 7 extracted shop sub-components
├── locker-room/         # Locker room components
├── ui/                  # Reusable UI primitives
└── Icon/                # Icon wrapper using lucide-react-native

hooks/
├── use-wallet-screen.ts # All wallet state, effects, and handlers
└── use-shop-screen.ts   # All shop state, effects, and handlers

lib/
├── api/                 # API client modules (wallet, shop, checkout, etc.)
├── revenuecat/          # RevenueCat in-app purchases provider
└── utils.ts             # Shared utilities

context/
├── user-context.tsx     # Authentication, user profile, team membership
├── collectibles-context.tsx # Owned packs and items
└── navbar-visibility-context.tsx

Architecture patterns

Screen files (wallet.tsx, shop.tsx) contain only imports + JSX. All state, effects, and handlers live in dedicated hooks:
  • hooks/use-wallet-screen.ts — wallet/token fetch, PIN verification, transactions
  • hooks/use-shop-screen.ts — cart state, product queries, checkout logic
Sub-components are extracted into components/wallet/ and components/shop/ with barrel exports.

Path aliases

Import using @/* alias (maps to project root):
import { useUser } from "@/context/user-context";
import { getTokenColors } from "@/lib/token-utils";
import type { Token } from "@/types/wallet.types";

Branding

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

Ecosystem overview

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