Before you begin, make sure you have set up your React Native development environment. This includes installing Node, Android Studio (for Android), and Xcode (for iOS on macOS).
Follow the official React Native documentation to set up your environment:
-
Install dependencies
npm install
-
Set up environment variables
Create a
.envfile using the example template:cp .env.example .env
Update the
.envfile with your configuration values. -
Create native folders
npm run prebuild
This will automatically set up the required files for development.
-
Start the app
npm run android
npm run ios
npm run web
For production Android releases, you'll need the actual secrets.properties file and wc_rn_upload.keystore. Get these from the mobile team or 1Password.
Required file locations:
- Place
secrets.propertiesin theandroid/directory - Place
wc_rn_upload.keystorein theandroid/app/directory
android/
├── secrets.properties ← Place here
└── app/
└── wc_rn_upload.keystore ← Place here
Build the release APK:
npm run android:buildThe release APK will be generated at android/app/build/outputs/apk/release/app-release.apk
Install on a device via USB:
Note: Make sure USB debugging is enabled on your Android device. Go to Settings → About phone → Tap "Build number" 7 times → Developer options → Enable "USB debugging".
-
Connect your device via USB and get its device ID:
adb devices
Example output:
V510BAC07114B000171 -
Build the release APK:
npm run android:build
-
Install the APK on your device (replace with your device ID):
adb -s V510BAC07114B000171 install android/app/build/outputs/apk/release/app-release.apk
⚠️ Security Note: Never commitsecrets.propertiesor keystore files to version control.
The app supports Over-The-Air (OTA) updates via EAS Update. This lets you push JavaScript-only changes to devices without rebuilding and redistributing the native app.
production— updates for production builds (Firebase/TestFlight releases)
Via GitHub Actions (recommended):
- Go to GitHub Actions → "OTA Update Mobile POS"
- Optionally add a message describing the changes
- Run the workflow
The workflow will automatically verify that no native changes are included. If native changes are detected, the workflow fails with a clear error — you must create a new native release first.
Via CLI:
cd dapps/pos-app
eas update --channel production --message "fix: description of changes"Open Settings in the app — the version text shows the current OTA update ID and channel.
OTA updates only deliver JavaScript bundle changes. The following require a full native release:
- Adding/removing native modules or permissions
- Changing
app.jsonnative configuration (iOS entitlements, Android permissions, etc.) - Upgrading the Expo SDK or React Native version
eas update:rollback --channel productionIf the app crashes after an OTA update, expo-updates automatically falls back to the previous working bundle.
To create a branded variant for a specific client:
-
Create a new branch
git checkout -b variant/<client-name>
-
Add the variant logo
- Add the client's logo to
assets/images/variants/<client-name>_brand.png - Requirements: PNG format
- Add the client's logo to
-
Add the printer logo in
constants/printer-logos.ts- Convert the client's logo to base64 using https://base64.guru/converter/encode/image/png
- Add the base64 string as a new constant:
export const <CLIENT_NAME>_LOGO_BASE64 = "data:image/png;base64,<base64-string>";
-
Define the variant in
constants/variants.ts- Import the printer logo at the top of the file:
import { // ... existing imports ... <CLIENT_NAME>_LOGO_BASE64, } from "./printer-logos";
- Add the variant name to the
VariantNametype:export type VariantName = | "default" | "solflare" | "binance" | "phantom" | "solana" | "<client-name>";
- Add the variant configuration to the
Variantsobject:<client-name>: { name: "<Client Name>", brandLogo: require("@/assets/images/variants/<client-name>_brand.png"), printerLogo: <CLIENT_NAME>_LOGO_BASE64, defaultTheme: "light", // or "dark" colors: { light: { "icon-accent-primary": "#HEXCOLOR", "bg-accent-primary": "#HEXCOLOR", "bg-payment-success": "#HEXCOLOR", "text-payment-success": "#HEXCOLOR", "border-payment-success": "#HEXCOLOR", }, dark: { // Same color keys as light theme }, }, },
- Import the printer logo at the top of the file:
-
Update Android version code in
app.json- Increment
expo.android.versionCode
- Increment
-
Commit, push, and create a release tag (Devin only)
git add . git commit -m "feat: add <client-name> variant" git push origin variant/<client-name> git tag variant-<client-name> git push origin variant-<client-name>
The tag will trigger the release workflow automatically.
-
Verify the release
- Check the build status and Firebase link in the
#system-releases-react-nativeSlack channel
- Check the build status and Firebase link in the
Manual release: If you need to trigger the release manually instead of using a tag, go to GitHub Actions and run the release-android-mobilepos workflow.