Non-custodial Stellar wallet for iOS and Android. Built with React Native, Zustand, and React Navigation.
For the Stellar organization's general contribution guidelines, see the Stellar Contribution Guide.
| Tool | Version | Install |
|---|---|---|
| Node.js | >= 22 | nodejs.org or nvm install 22 — team runs v22 locally |
| Yarn | 4.10.0 | corepack enable && corepack prepare yarn@4.10.0 --activate |
| Ruby | 3.1.4 | rbenv or rvm — team runs 3.1.4 locally |
| CocoaPods | 1.15.2 | gem install cocoapods -v 1.15.2 — must match Podfile.lock version |
| Watchman | Latest | brew install watchman |
| JDK | 17 | Adoptium or Android Studio |
| Xcode | Latest stable | Mac App Store (iOS only) |
| Android Studio | Latest stable | developer.android.com |
| Maestro CLI | Latest | brew install mobile-dev-inc/tap/maestro (e2e tests only) |
Android SDK requirements (install via Android Studio SDK Manager):
- SDK Platform API 36, Build-Tools 36.0.0, NDK 28.2.13676358
Shell environment — add to ~/.zshrc or ~/.bashrc (choose the
ANDROID_HOME line for your OS, comment out the others):
# macOS
export ANDROID_HOME=$HOME/Library/Android/sdk
# Linux
# export ANDROID_HOME=$HOME/Android/Sdk
# Windows (Git Bash / WSL)
# export ANDROID_HOME=$HOME/AppData/Local/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-toolsFor full platform setup, see the React Native Environment Setup guide.
If you use an LLM-powered coding assistant, you can automate the setup. The repo
includes a quick start guide (quick-start-guide.md)
that checks your environment, installs missing tools, configures .env, and
verifies the build.
Point your coding assistant at quick-start-guide.md and ask it to follow the
steps.
For detailed best practices and coding guidelines when working with an LLM, see
docs/skills/freighter-mobile-best-practices.
The skill will:
- Check all prerequisites (Node, Yarn, Ruby, JDK, Xcode, Android SDK, etc.)
- Install what it can automatically (with your confirmation)
- Produce a list of manual steps for anything it couldn't install
- Guide you through setting up
.env— what each variable is and how to obtain it (WalletConnect dashboard, your own backend instances, etc.) - Run verification to confirm the build works
If you don't use an LLM assistant, follow the manual setup below.
git clone https://github.com/stellar/freighter-mobile.git
cd freighter-mobile
bundle install # Ruby deps (Fastlane, CocoaPods)
yarn install # Node deps + auto-runs postinstall (Husky, polyfills, pods)
cp .env.example .env # Then fill in values (see below)Copy .env.example to .env and fill in the values. The .env file must
never be committed.
Required — app won't build or function without these:
| Variable | How to set up |
|---|---|
FREIGHTER_BACKEND_V1_DEV_URL |
Run your own backend from stellar/freighter-backend |
FREIGHTER_BACKEND_V2_DEV_URL |
Run your own backend-v2 from stellar/freighter-backend-v2 |
WALLET_KIT_PROJECT_ID_DEV |
Create a free project at dashboard.walletconnect.com — sign up, create a new project (type: Wallet), copy the Project ID |
WALLET_KIT_MT_NAME_DEV |
Your project name from the WalletConnect dashboard |
WALLET_KIT_MT_DESCRIPTION_DEV |
Your project description |
WALLET_KIT_MT_URL_DEV |
Your project URL |
WALLET_KIT_MT_ICON_DEV |
Your project icon URL |
WALLET_KIT_MT_REDIRECT_NATIVE_DEV |
Deep link matching what you've configured on the WalletConnect dashboard |
ANDROID_DEBUG_KEYSTORE_PASSWORD |
Android Studio's default: android |
ANDROID_DEBUG_KEYSTORE_ALIAS |
Android Studio's default: androiddebugkey |
Optional — features degrade gracefully without these:
| Variable | Notes |
|---|---|
AMPLITUDE_API_KEY |
Auto-disabled in __DEV__ mode — not needed for local dev |
SENTRY_DSN |
Leave empty — errors log to console instead |
FREIGHTER_BACKEND_*_STG_URL / *_PROD_URL |
Only needed for staging/prod builds. Run your own backend from stellar/freighter-backend and backend-v2 from stellar/freighter-backend-v2 |
WALLET_KIT_*_PROD (6 vars) |
Only needed for prod builds — same setup as dev vars above |
ANDROID_PROD_KEYSTORE_* |
Only needed for release builds — generate a separate keystore |
MP_COLLECTIONS_ADDRESSES |
Comma-separated list — leave empty if not working on collectibles |
E2E testing only:
⚠️ Security warning: The recovery phrase used for E2E tests must be from a wallet with no real funds. Never use a mainnet-funded wallet for automated testing.
| Variable | Notes |
|---|---|
IS_E2E_TEST |
Set to true when running Maestro |
E2E_TEST_RECOVERY_PHRASE |
Generate a new wallet via any Stellar wallet and copy the 12/24-word phrase (used by CreateWallet/ImportWallet flows) |
E2E_TEST_FUNDED_RECOVERY_PHRASE |
Recovery phrase for a dedicated low-balance mainnet test wallet only. Never use a personal wallet or any wallet holding meaningful funds. Required by SendClassicTokenMainnet and SwapClassicTokenMainnet flows which execute real transactions on mainnet. Fund the account with a small amount of XLM before running these tests. |
See .env.example for the full list with inline comments.
yarn ios # iOS simulator (dev)
yarn android # Android emulator (dev)
yarn start # Metro bundler only (starts automatically with above)Dev and prod builds use separate bundle IDs (org.stellar.freighterdev /
org.stellar.freighterwallet) and can coexist on the same device. See
package.json for all run commands including device and release variants.
yarn test # Jest unit tests
yarn check # All checks (TypeScript + ESLint + Prettier)
yarn fix # Auto-fix lint + format
yarn lint:translations # Check for missing i18n keys
yarn test:e2e:ios <flow> # Maestro e2e (iOS)
yarn test:e2e:android <flow> # Maestro e2e (Android)Cleaning builds (escalation order):
yarn start-c # Clear Metro cache
yarn pod-install # Reinstall CocoaPods
yarn gradle-clean # Clean Gradle build cache (Android)
yarn node-c-install # Remove node_modules + reinstall
yarn c-install # Full clean (Gradle + node_modules + reinstall)
yarn r-install # Nuclear: reset env + rebuild everythingSee package.json for the complete list of scripts.
freighter-mobile/
├── src/
│ ├── components/ # React Native components (screens, templates, primitives)
│ ├── ducks/ # Zustand state stores
│ ├── hooks/ # Custom React hooks
│ ├── helpers/ # Utility functions
│ ├── services/ # Business logic & API calls
│ ├── navigators/ # React Navigation stack/tab definitions
│ ├── providers/ # Context providers
│ ├── config/ # App configuration
│ ├── types/ # TypeScript type definitions
│ └── i18n/ # Translations (i18next)
├── __tests__/ # Jest unit tests (mirrors src/)
├── e2e/ # Maestro e2e tests + docs
├── ios/ / android/ # Native projects
└── scripts/ # Build and setup scripts
- Formatting: Double quotes, 2-space indent, trailing commas, 80-char width,
semicolons. Enforced by Prettier (
.prettierrc.json). - Linting: Airbnb + TypeScript strict + custom translations plugin. Config
in
eslint.config.mjs. - Absolute imports: Always from
src/root — no relative paths. Enforced by ESLint. - Arrow functions: Required for React components. Enforced by ESLint.
- Import sorting: Auto-handled by
@trivago/prettier-plugin-sort-imports. - JSDoc: Required on all new/modified public functions (see PR template).
- Translations: All user-facing strings through
i18next. UseuseAppTranslationhook. The custom ESLint plugin flags missing translations.
Husky runs on every commit:
lint-staged— ESLint fix + Prettier on staged filesyarn test— full unit test suiteyarn lint:ts— TypeScript type check
All must pass before the commit succeeds.
Unit tests: Jest with @testing-library/react-native. Tests in
__tests__/, mocks in __mocks__/.
E2E tests: Maestro flows in e2e/flows/ — see the e2e docs for
setup, writing tests, and debugging.
Before submitting a PR: yarn test + yarn lint:ts must pass. Test on both
iOS and Android, including small screens.
- Create the screen component in
src/components/screens/ - Add the route to
src/config/routes.ts - Register in the appropriate navigator in
src/navigators/ - Add translations for all user-facing strings in
src/i18n/ - Add tests in
__tests__/
- Create the store file in
src/ducks/(e.g.,src/ducks/myFeature.ts) - Define the store using Zustand's
createwith typed state and actions - Export a hook for consuming the store (e.g.,
useMyFeatureStore) - Add tests in
__tests__/ducks/
- Use the existing
isIOSandisAndroidhelpers for platform checks - Use
.ios.tsx/.android.tsxfile extensions for larger divergences - Test on both platforms — especially native module interactions, gestures, and keyboard behavior
The app connects to two separate backend services:
- V1 (stellar/freighter-backend, TypeScript) — balances, token prices, token details, account history, contract specs, transaction simulation, transaction submission
- V2 (stellar/freighter-backend-v2, Go) — protocols (Discovery screen), collectibles
To run your own:
- Clone the repo for the backend you need (V1, V2, or both)
- Follow its README for setup
- Point
FREIGHTER_BACKEND_V1_DEV_URLand/orFREIGHTER_BACKEND_V2_DEV_URLin your.envat your local instance
- Branch from
mainusing your initials + description:lf-feature-name,cg-fix-token-display - Commit messages: start with action verb (
Add,Fix,Update,Improve) - No mixed concerns — keep refactoring separate from features
- Include before/after screenshots for UI changes
- Follow the full checklist in the PR template
CI runs on every PR: unit tests (test.yml), iOS e2e (ios-e2e.yml),
Android e2e (android-e2e.yml). All must pass.
Freighter handles private keys and signs transactions. When contributing:
- Never log or expose private keys, seed phrases, or passwords
- Use
react-native-keychain(iOS Keychain / Android Keystore) for secrets — never AsyncStorage - Validate all external data — WalletConnect payloads, API responses, deep links
- Don't weaken Blockaid transaction scanning or
jail-monkeyjailbreak detection - Report vulnerabilities via the Stellar Security Policy — not public issues
For the auth security model, read src/ducks/auth.ts directly — it is the
source of truth for the authentication state machine.
| Topic | Location |
|---|---|
| WalletConnect RPC methods | docs/walletconnect-rpc-methods.md |
| E2E testing (6 guides) | e2e/docs/ |
| Mock dApp for testing | mock-dapp/README.md |
| Release process | RELEASE.md |
| All scripts & commands | package.json |
| Best practices (LLM guide) | docs/skills/freighter-mobile-best-practices |
Questions? Open a GitHub Discussion or join the Stellar Developer Discord.