The mobile client for Paycrest, built with Expo (SDK 53) and React Native. The app uses Privy for embedded wallets and authentication, Paycrest for swap/payout orders, and LiFi for chain/token metadata.
- Node 20+ and Yarn (or npm)
- Watchman (macOS) —
brew install watchman - Xcode 15+ and CocoaPods for iOS
- Android Studio + JDK 17 for Android
- EAS CLI for cloud builds:
npm install -g eas-cli - Expo Orbit (optional, useful for installing dev builds on simulators)
# 1. Install deps
yarn install
# 2. Create your local env file from the template
cp .env.example .env
# …then fill in the values (see "Environment variables" below)
# 3. Generate native projects if missing, then start the dev client
yarn prebuild
yarn ios # or: yarn android
yarn start # Metro bundler; opens a dev-client buildThe first
yarn ios/yarn androidwill compile a native dev client. After that,yarn startis enough.
There are three environments: development, staging, and production. They share the same bundle identifier (com.paycrest.noblocks), so only one variant can be installed on a device at a time. They differ only by environment variables and EAS build channel.
| Environment | EAS profile | Channel | Notes |
|---|---|---|---|
| Development | development |
development |
Dev client, internal distribution, simulator-friendly |
| Staging | staging |
staging |
Internal distribution (APK / ad-hoc iOS) |
| Production | production |
production |
App Store / Play Store, auto-incremented version |
All variables are documented in .env.example. The codebase reads them via process.env.EXPO_PUBLIC_* (see api/queryConstants.ts, api/apiClient.ts, app/_layout.tsx).
| Variable | Description |
|---|---|
EXPO_PUBLIC_APP_ENV |
One of development / staging / production |
EXPO_PUBLIC_API_BASE_URL |
Paycrest API base URL |
EXPO_PUBLIC_API_KEY |
Paycrest API key |
EXPO_PUBLIC_PRIVY_BASE_URL |
Privy REST base URL |
EXPO_PUBLIC_PRIVY_APP_ID |
Privy app ID |
EXPO_PUBLIC_PRIVY_CLIENT_ID |
Privy client ID |
EXPO_PUBLIC_PRIVY_APP_SECRET |
Privy app secret (inlined — handle with care) |
Anything prefixed with
EXPO_PUBLIC_is inlined into the JS bundle and shipped to users' devices. Do not put true server-only secrets in this app.
Expo's bundler auto-loads .env, .env.local, .env.development, .env.development.local, .env.production, .env.production.local based on NODE_ENV (see Expo env vars).
For day-to-day local development against the dev API, keep your values in .env (or .env.development). To run a local build pointed at staging or production, override per-shell:
# Point local dev at staging API
cp .env.example .env.staging # fill in staging values
cp .env.staging .env # use it as the active env
yarn startThe three build profiles live in eas.json. Each profile sets APP_ENV / EXPO_PUBLIC_APP_ENV automatically.
# Authenticate once
eas login
# Link this repo to your EAS project (writes extra.eas.projectId)
eas init
# Create a build per environment
eas build --profile development --platform ios
eas build --profile staging --platform android
eas build --profile production --platform allEXPO_PUBLIC_* variables must exist in the build environment when EAS compiles the JS bundle. Choose one of:
- EAS environment variables (recommended) — store per-environment values in the EAS dashboard or via the CLI:
eas env:create --environment preview --name EXPO_PUBLIC_PRIVY_APP_ID --value <value>
- Inline in
eas.json— add non-sensitive values directly under each profile'senvblock. - Local
.env.<profile>file — present when runningeas buildlocally; EAS will pick it up via Expo's dotenv loader.
The build profiles already declare channel values, so EAS Update just needs to be wired into app.json:
eas update:configure
eas update --branch staging --message "Fix bottom sheet on small screens"
eas update --branch production --message "Hotfix"app/ Expo Router screens (file-based routing)
api/ Axios client, query functions, types
components/ Shared UI
hooks/ Custom hooks (auth, payments, dimensions, fonts)
constants/ Colors, Size scale
utils/ Helpers (privy, sample data, styles)
assets/ Fonts and images
ios/, android/ Native projects (regenerated via `yarn prebuild`)
patches/ Patch-package patches applied on postinstall
schema/ Yup validation schemas
scripts/ Maintenance scripts
| Command | What it does |
|---|---|
yarn start |
Start Metro and open a dev client |
yarn ios |
Build and run on the iOS simulator/device |
yarn android |
Build and run on the Android emulator/device |
yarn web |
Run the web target |
yarn lint |
ESLint |
yarn prebuild |
Regenerate ios/ and android/ from config |
process.env.EXPO_PUBLIC_*isundefined— your.envfile isn't loaded. Restart Metro withexpo start --clear.- Privy errors on launch — make sure
EXPO_PUBLIC_PRIVY_APP_IDandEXPO_PUBLIC_PRIVY_CLIENT_IDmatch the environment you're pointing at. eas buildrejects the project — runeas initto write your project ID intoapp.json#extra.eas.projectId.