Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 174 additions & 23 deletions repositories/d-sports-engage-native.mdx
Original file line number Diff line number Diff line change
@@ -1,47 +1,198 @@
---
title: "d-sports-engage-native"
description: "Native iOS and Android app for D-Sports Engage. Expo 54, React Native, Clerk, RevenueCat, Thirdweb."

Check warning on line 3 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L3

Did you really mean 'Thirdweb'?
icon: "smartphone"
---

## 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.

Check warning on line 9 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L9

Did you really mean 'leaderboard'?

- **Run:** `bunx expo start` or `bun run start` — then press `a` for Android or `i` for iOS, or scan the QR code with Expo Go.
- **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

| Category | Technology |
| ---------- | ------------------------- |
| Framework | Expo 54, React Native 0.81, React 19 |
| Auth | Clerk (Expo) |
| Payments | RevenueCat (react-native-purchases) |
| Web3 | Thirdweb |
| State | Zustand |
| Storage | MMKV |
| UI | Lucide React Native |
| Navigation | Expo Router |
| Package | Bun |
| Category | Technology |
| ----------- | ------------------------------------------- |
| Framework | Expo 54, React Native 0.81, React 19 |
| Auth | Clerk (`@clerk/clerk-expo`) |
| Payments | RevenueCat (`react-native-purchases`) |
| Web3 | Thirdweb SDK |

Check warning on line 22 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L22

Did you really mean 'Thirdweb'?
| State | Zustand 5 + React Context |

Check warning on line 23 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L23

Did you really mean 'Zustand'?
| Storage | MMKV (synchronous persistence) |
| UI | Lucide React Native |

Check warning on line 25 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L25

Did you really mean 'Lucide'?
| Navigation | Expo Router 6 (file-based routing) |
| Animations | React Native Reanimated 4 |
| Monitoring | Sentry (`@sentry/react-native`) |
| Package | Bun |

## 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)
- **Wallet** — token balances, holdings, pack opening, crypto checkout (via PWA backend), PIN verification

Check warning on line 33 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L33

Did you really mean 'crypto'?
- **Shop** — collectibles, cart, coin bundles, crypto and fiat checkout

Check warning on line 34 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L34

Did you really mean 'crypto'?
- **Leaderboard** — rankings and filters

Check warning on line 35 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L35

Did you really mean 'Leaderboard'?
- **Locker room** — social feed, teams, quests, daily games (Pick'Em, Spin Wheel, Guess the Player)

Check warning on line 36 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L36

Did you really mean 'Pick'Em'?
- **Profile** — user profile, settings, and account management
- **Theme** — dark/light mode (default dark)
- **PWA support** — `display: standalone`, responsive desktop layout (max 480 px), web hover states

Check warning on line 39 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L39

Did you really mean 'px'?

## Getting started

1. Clone the repository and run `bun install`.
2. Configure environment (Clerk, RevenueCat, Thirdweb, API base URL) per repo README.
3. Run `bunx expo start`.
4. For development builds: `bun run build:dev` (EAS) or run with Expo dev client.
<Steps>
<Step title="Install dependencies">
```bash
bun install
```
</Step>
<Step title="Configure environment">
Create a `.env` file in the project root with the following variables:

The app targets both native and web (responsive) and uses the same backend (d-sports-api) as the PWA for API and checkout flows.
| Variable | Description |
| -------- | ----------- |
| `EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY` | Clerk publishable key |
| `EXPO_PUBLIC_API_URL` | API backend URL (e.g. `https://api.d-sports.org`) |
| `EXPO_PUBLIC_TW_CLIENT_ID` | Thirdweb client ID |
| `EXPO_PUBLIC_REVENUECAT_API_KEY` | RevenueCat API key |
| `EXPO_PUBLIC_REVENUECAT_APPSTORE_ID` | RevenueCat App Store ID |
| `EXPO_PUBLIC_REVENUECAT_ENTITLEMENT` | RevenueCat entitlement name |
| `EXPO_PUBLIC_SUPABASE_URL` | Supabase project URL |
| `EXPO_PUBLIC_SUPABASE_KEY` | Supabase publishable key |

<Note>Only `EXPO_PUBLIC_*` variables are accessible at runtime in the Expo app.</Note>
</Step>
<Step title="Start the dev server">
```bash
bunx expo start

Check warning on line 67 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L67

Did you really mean 'bunx'?
```
Press **a** for Android, **i** for iOS, or scan the QR code with Expo Go.
</Step>
<Step title="Type-check">
```bash
bun tsc --noEmit

Check warning on line 73 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L73

Did you really mean 'tsc'?
```
</Step>
</Steps>

## Project structure

```text
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

Check warning on line 128 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L128

Did you really mean 'Zustand'?
- **React Context** providers for authentication (`UserContext`), collectibles (`CollectiblesContext`), and navbar visibility

Check warning on line 129 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L129

Did you really mean 'navbar'?

### 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.

Check warning on line 140 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L140

Did you really mean 'Crypto'?

Check warning on line 140 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L140

Did you really mean 'Thirdweb'?

Check warning on line 140 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L140

Did you really mean 'Arbitrum'?

Check warning on line 140 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L140

Did you really mean 'Ethereum'?

### Path alias

Use the `@/*` alias to import from the project root:

```typescript
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

| Profile | Purpose | Command |
| ------------- | ------------------------ | --------------------------- |
| `development` | Dev client (simulator) | `bun run build:dev` |
| `preview` | Internal QA (APK/ad hoc) | `bun run build:preview` |

Check warning on line 160 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L160

Did you really mean 'hoc'?
| `production` | Store-ready | `bun run build:prod` |

### OTA updates

Push JS-only changes without a new store build:

```bash
bun run update --branch production --message "Fix: wallet balance display"
```

| Build profile | Update channel | Audience |
| ------------- | -------------- | --------------- |
| `development` | `development` | Dev builds |
| `preview` | `preview` | Internal testers |
| `production` | `production` | App Store users |

<Warning>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`.</Warning>

### Store submission

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

## Branding

| Token | Value |
| ----------------- | ----------- |
| Base background | `#0a0e1a` |
| Accent gold | `#F5C842` |
| Primary blue | `#4169E1` |
| Default theme | Dark |

<Card title="Ecosystem overview" icon="map" href="/repositories/ecosystem-overview">
See how the native app fits with the PWA, site, and Mic'd Up.

Check warning on line 197 in repositories/d-sports-engage-native.mdx

View check run for this annotation

Mintlify / Mintlify Validation (chronoscyberchronicles) - vale-spellcheck

repositories/d-sports-engage-native.mdx#L197

Did you really mean 'Mic'd'?
</Card>