Rainbow wallet: a React Native codebase where the build reads your .env
🌈‒ the Ethereum wallet that lives in your pocket
At a glance
- What is it?
- Rainbow is the TypeScript React Native wallet for iOS, Android and browser extensions. Its contributor setup is the hard part: a postinstall hook that needs a private sibling repo, a JDK 17 requirement that Android Studio fights you on, and a rule that Android Studio must always be launched from the terminal.
- Who is it for?
- Adopt this repository if you are an external contributor who wants to work on a React Native wallet in both native trees at once, and if you can supply your own Etherscan, Infura and Firebase credentials. Skip it if you want to run a wallet today, because the shipped path is a store download, and if you are on Linux for the iOS tree.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- rainbow-me/rainbow4,402 ★ · +7
| Repository | 2026-09-23 | 2026-11-13 |
|---|---|---|
| rainbow-me/rainbow | 4.4k | 4.4k |
7 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The wallet's own build is a private two-step pipeline
Rainbow ships to the iOS App Store, Google Play and the Chrome, Brave, Edge, Firefox and Arc extension stores. It is a React Native app written in TypeScript, and the interesting part for an engineer is not the wallet logic but the build pipeline: package.json carries both a browser field and a react-native field that remap Node core modules to shims: filesystem calls resolve to react-native-level-fs, HTTP to @tradle/react-native-http and sockets to react-native-tcp. A postinstall script reads your environment file and generates build configs before anything compiles.
That order matters. Two contributor paths exist and they are not equivalent: internal developers authenticate the GitHub CLI and clone the private rainbow-scripts repository into the project root, while external contributors copy the example environment file and supply their own keys.
yarn install reads .env and a sibling repo the public tree does not have
The README places this warning before the install command itself, which is the clearest signal that it is the crux: set up the environment first, because the postinstall script reads `.env` and rainbow-scripts to generate build configs and run prebuild hooks. For an external contributor the whole of that reduces to two files. `.env` is yours. `google-services.json` must come from a personal Firebase project registered under the package name `me.rainbow`, and for Google Drive backup and restore to work in your builds you also register your signing keystore SHA-1 fingerprint as an Android OAuth client in that project's console.
The iOS side is friendlier by one step. `GoogleService-Info.plist` is already committed, and the postinstall script patches its API key from `GOOGLE_SERVICE_API_KEY` in your `.env`. So the two platforms have deliberately different friction: Android needs a project registered in someone else's namespace, iOS needs one key.
Once the files exist, install and setup are two commands:
yarn install && yarn setupExpect that to be the longest step, not the last one. The keys `.env.example` asks for include `ETHERSCAN_API_KEY`, `ETH_GAS_STATION_API_KEY`, `IMGIX_DOMAIN`, `IMGIX_TOKEN` and per-chain RPC endpoints for Ethereum mainnet and Goerli plus Polygon, Arbitrum and Optimism. The README states plainly that some features are currently not accessible to external contributors while the team works with its data providers on open source API keys.
Android Studio's bundled JDK 21 is the documented cause of build failure
This is the sharpest failure mode in the whole setup, and it is not a guess: the README tells you not to use the JDK bundled with Android Studio because it is JDK 21, which causes build failures, and links the React Native environment notes. Install Zulu 17 instead:
brew install --cask zulu@17Then export the paths the Gradle build and the emulator expect:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
export ANDROID_HOME=$HOME/Library/Android/sdk # macOS
# export ANDROID_HOME=$HOME/Android/Sdk # Linux
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-toolsTwo more settings have to move before anything works. Raise the IDE heap to at least 4096 MB in Android Studio's Memory Settings, because the default 2048 MB causes slow syncs and builds on a project of this size. Then point Settings, Build, Execution, Deployment, Build Tools, Gradle, Gradle JDK at the JAVA_HOME entry rather than the bundled JDK 21, restart your terminals, and create a device through Device Manager unless you are using hardware.
The first Gradle run must come from a terminal, and the IDE must follow it
The ordering here is unusual enough that it deserves to be stated plainly, because skipping either step produces a failure whose message points somewhere else. Build once from the command line so Gradle generates the native headers Android Studio needs for sync:
cd android && ./gradlew assembleDebug && cd ..Then quit Android Studio entirely and reopen it from the terminal rather than from Spotlight or the Dock:
open -a "Android Studio" # macOSThe README states the reason without softening it: launching from Spotlight or the Dock causes Gradle sync to fail with "Cannot run program node". That failure happens because node arrives on the PATH through mise, and a GUI launch does not inherit your shell environment. It is a close-reading catch worth pausing on, because the same cause explains why the toolchain step insists on shell activation, and why step one of the prerequisites is mise at all rather than a versioned node installed by a package manager. The catch has a second edge: mise must be shell-activated so tool versions auto-switch when you `cd` into the repo, which means the README's own advice cannot be followed by a GUI launcher.
mise pins the toolchain, then corepack has to be enabled by hand
Rainbow does not ship an install script. What it ships is a toolchain declaration in `mise.toml` plus pinned versions in `.node-version`, `.ruby-version` and `.xcode-version`, and the build runs those versions. The prerequisite sequence is three steps: install mise, run `mise install` from the repo root to install all pinned tools, then enable yarn through corepack.
curl https://mise.run | shFor iOS, which the README marks macOS only, install the pinned Xcode through the `xcodes` CLI, which reads `.xcode-version` automatically, and add Watchman:
brew install xcodesorg/made/xcodes
xcodes installbrew install watchmanCI and Bitrise build against the same pin, so local parity is the point of the file rather than a convenience. Bundles and Pods come next through `yarn install-bundle && yarn install-pods`, and a contributor tip points internal developers at the separate rainbow-me/rainbow-setup script, which installs all dependencies and configures the project in one step. That script is not the path an outsider can take.
Metro serves the bundle, and iOS opens a workspace rather than a project
Once the native trees are configured, running the app is two terminals and one file choice. Start Metro:
yarn startFor iOS, open `ios/Rainbow.xcworkspace` in Xcode, not the `.xcodeproj`, then press Cmd+R, or run `yarn ios` from the terminal. For Android, open the `android/` folder in Android Studio, or run `yarn android`. The workspace distinction is the usual CocoaPods consequence of Pods adding targets, but it is the kind of detail that costs a new contributor an afternoon when Xcode reports missing build phases instead of missing Pods.
On Linux, the Android path still applies and needs `sudo apt install libsecret-tools watchman`. The iOS path does not. The repository also carries `e2e/`, `bitrise.yml`, a dependency-cruiser config carrying separate per-platform dependency baselines, and a TypeScript-to-JavaScript error baseline file, which is how a codebase this size keeps a migration from turning into a thousand-item review comment. The project is not archived and its last push was on 2026-11-02.
Where Rainbow differs from a browser-extension-only wallet
The alternative worth naming is a wallet distributed only as a browser extension, where there is no native tree at all. The difference is architectural rather than a matter of taste. A browser-only wallet inherits the browser's network stack and its storage, ships one JavaScript bundle, and installs in seconds with no Xcode pin, no JDK selection and no Gradle JDK setting. Rainbow maintains an iOS binary and an Android binary from one TypeScript source tree, which is what buys a shared codebase and costs every contributor the toolchain above.
That trade shows up in the file list. React Native configs in `react-native.config.js`, `metro.config.js` and `app.config.ts` sit beside the two platform folders, and `InjectedJSBundle.js` and `shim.js` sit at the repository root. There are also two dependency-check baselines, one per platform, which only makes sense if the two targets genuinely diverge in what they can import.
The GPL-3.0 licence covers the repository. Anyone planning to reuse the code in a closed product needs to read what that obliges before treating the wallet logic as a starting point, and the README does not document a separate licensing carve-out for the app stores.
Editorial conclusion
Adopt this repository if you are an external contributor who wants to work on a React Native wallet in both native trees at once, and if you can supply your own Etherscan, Infura and Firebase credentials. Skip it if you want to run a wallet today, because the shipped path is a store download, and if you are on Linux for the iOS tree. Verify first that yarn install completes without the private rainbow-scripts checkout, since that postinstall hook is where external setup diverges from internal setup.
Frequently asked questions
What does rainbow-me/rainbow need before yarn install will succeed?
External contributors copy .env.example to .env, supply their own google-services.json in android/app from a Firebase project registered under the package name me.rainbow, and then run yarn install && yarn setup. Internal developers instead authenticate the GitHub CLI and clone rainbow-me/rainbow-scripts into the project root, because the postinstall prebuild hooks depend on it.
Which JDK does the Rainbow Android build require, and why?
JDK 17, installed as Azul Zulu 17. The README says not to use the JDK bundled with Android Studio because it is JDK 21, which causes build failures, and to point the Gradle JDK setting at the JAVA_HOME entry instead.
Can I build the rainbow-me/rainbow iOS app on Linux?
No. The README labels the iOS setup macOS only, and asks for the Xcode version pinned in .xcode-version along with Watchman. Linux is supported for the Android side, where it also requires libsecret-tools and watchman as system dependencies.
Why does Gradle sync in Rainbow fail with Cannot run program node?
Because Android Studio was launched from Spotlight or the Dock instead of the terminal, so it did not inherit your shell PATH where mise puts node. Launch it with open -a "Android Studio" after running the first build from the terminal.
What licence is the rainbow-me/rainbow repository released under?
The repository is GPL-3.0. The README does not document any separate licensing carve-out for the store builds.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rainbow-me-rainbow)Star history chart for your README
[](https://hysenlabs.com/projects/rainbow-me-rainbow)Was this useful?