← Back to list

Building A Mobile EVM Wallet With React Native

Understanding The Tech Behind Building A Mobile Blockchain Application

Manny · 2026-06-11 18:25 · 2 claps · 6.7 min read
#evm #mobile-app-development #react-native #blockchain
Open on Medium ↗
Wiki topics: CRY · Crypto & Web3 🌐 · Web Development 📱 · Mobile Development

Building A Mobile EVM Wallet With React Native

Understanding The Tech Behind Building A Mobile Blockchain Application

Building An iOS Mobile Wallet with React Native

Building An iOS Mobile Wallet with React Native

The goal of this article isn’t to go through step-by-step building the application (you can do that with AI), but more so understanding the tech needed to build a mobile iOS app for an EVM wallet so that it can help you build one in the future.

EVM iOS Wallet

EVM iOS Wallet

For the sake of this article, we’ll be focusing specifically on iOS to understand its features, limitations and work arounds.

The functionality we’ll limit ourselves to are:

1 — Setup and manage a new wallet with a passphrase

2 — Backup the passphrase

3 — Add an RPC

4 — Retrieve Balance

5 — Transfer Transaction

Why React Native & Expo

React Native & Expo

React Native & Expo

React Native lets you write your UI once in JavaScript and ship to both iOS and Android. When it comes to a wallet app, the real selling point is the update model. Native Swift apps must go through Apple’s review process for every change, which can take days. React Native (especially with Expo’s over-the-air updates via EAS Update) lets you push JS-layer fixes instantly, without a new App Store submission. For a wallet, where a bug could mean lost funds, that matters enormously.

Expo specifically adds a lot out of the box: **expo-secure-store for Keychain access, `expo-local-authentication`** for biometrics, and a managed build pipeline (EAS Build) that handles the notoriously painful iOS signing and provisioning certificates. You get a familiar React development experience instead of learning Swift and UIKit from scratch.

The tradeoff can be rough though. React Native has a reputation for being finicky. Native modules occasionally break between Expo SDK versions, the Metro bundler has its quirks, and you’ll hit moments where something works on Android but not iOS or vice versa. The bridge between JS and native code also adds a thin layer of complexity when you’re doing security-sensitive work.

Factoring this all in, most production mobile wallets have made exactly this bet. ***Rainbow Wallet and [Coinbase Wallet SDK](https://github.com/coinbase/wallet-mobile-sdk) ***are all built on React Native.

What’s Not So Simple

Features 1, 3, and 4 are straight forward in terms of their functionality when prompting most LLMs. Backing up a passphrase and interacting with it correctly is the complicated part. Correctly in this case is securely, or as secure as possible.

iCloud Backup & Keychain

iCloud Backup & Keychain

iCloud Backup & Keychain

The naive approach to backing up a seed phrase seems simple: save it to iCloud or store it in the iOS Keychain, and retrieve it when needed. The problem is how you retrieve it; it’s in plain text.

iCloud Drive storage is essentially a synced filesystem. A file containing your 12-word mnemonic would sit on Apple’s servers, sync to every signed-in device, and be readable by your app (and anything that can compromise your app) as a raw string. That’s not a backup strategy; it’s a liability.

The iOS Keychain is better. It’s encrypted storage tied to your app’s bundle identifier, sandboxed from other apps, and persistent across reinstalls. You can gate items with **kSecAttrAccessible flags like `WhenUnlockedThisDeviceOnly** to prevent the item from being included in unencrypted backups or read on other devices. You can even addkSecAccessControl` with a biometric requirement so that reading the item triggers a Face ID prompt.

There’s still a fundamental ceiling here. When your app reads a Keychain item, the raw bytes surface in app memory. At that moment, a compromised JavaScript bundle, a malicious dependency in your **node_modules**, or a memory-inspection attack could exfiltrate the mnemonic. While Keychain is a good base, it’s ultimately not the final solution itself.

Apple On-Device Secure Enclave

Apple Secure Enclave (SE)

Apple Secure Enclave (SE)

Apple’s answer to the memory-exposure problem is the Secure Enclave (SE), which is a dedicated security coprocessor built into every iPhone since the 5s, isolated from the main application processor.

The key design principle: private keys generated inside the SE never leave it. Your application never holds the private key in memory. Instead, you send data to the SE, the SE performs the cryptographic operation (signing, decryption), and returns only the result. Even if your app, the OS, or the entire file system is compromised, the SE’s keys remain inaccessible.

Secure Enclave Sequence Diagram

Secure Enclave Sequence Diagram

The SE has its own encrypted memory, a hardware random number generator, and runs its own microkernel. When you require biometric authentication to use an SE key, the biometric check happens inside the SE itself and not in the OS where it could be spoofed. It’s the closest thing to a hardware wallet built into your phone.

Supported Cryptographic Algorithm Elliptical Curves

Elliptical Curves

Elliptical Curves

Here’s where EVM wallet development hits its biggest wall. The Secure Enclave only supports ECDSA on the NIST P-256 curve (**kSecAttrKeyTypeECSECPrimeRandom**). It does not support:

  • secp256k1 — the elliptic curve used by Ethereum and Bitcoin ❌
  • ed25519 — used by Solana ❌
  • Arbitrary data storage — you can’t put a 24-word mnemonic inside the SE ❌

You cannot put an Ethereum private key inside the Secure Enclave and have it sign transactions directly. The SE will simply refuse. This is the single biggest constraint in iOS wallet design, and it forces every major mobile wallet into the same architectural workaround.

Encryption Workaround

Since we can’t store secp256k1 keys in the SE directly, we use the SE for what it does support, which is to use that capability to protect what we actually need to store. This is the pattern used by most wallets.

Encryption Workaround

Encryption Workaround

The SE-wrapped encryption key pattern:

  1. Generate a P-256 keypair inside the Secure Enclave, gated by biometric authentication. The private key never leaves the SE.
  2. Generate an AES-256 symmetric key (the “wrapping key”) and store it in the Keychain.
  3. Encrypt the wrapping key using the SE’s P-256 public key. Store the ciphertext.
  4. Encrypt your mnemonic / secp256k1 private keys with the AES key. Store the ciphertext in Keychain or on disk.

To sign an Ethereum transaction:

Biometric prompt triggers → SE unwraps the AES key → AES key decrypts the mnemonic → derive the secp256k1 private key → sign → immediately zero the memory.

The mnemonic is in plaintext for milliseconds, only after a successful biometric prompt, and the root of trust (the SE keypair) is hardware-bound and non-exportable. No amount of JS compromise can extract the SE key.

iOS Simulator Limitations

iOS Simulator

iOS Simulator

The iOS Simulator runs on your Mac’s x86/ARM processor, which means it doesn’t have a Secure Enclave. Biometric APIs exist in the Simulator, but Face ID is simulated (you trigger it via the menu: Features → Face ID → Matching Face) and **kSecAttrTokenIDSecureEnclave** operations simply fail or are silently downgraded.

This means you need two code paths:

  • Simulator: Fall back to standard Keychain storage without SE-backed keys. You can use **expo-secure-store** directly, or generate a software P-256 key stored in Keychain as a stand-in.
  • Physical device: Full SE-backed key generation with real biometric gating. NOTE: Due to the additional native modules needed, an Apple Paid Developer account is needed to build and deploy on your device for testing.

In practice, you’d detect this with a runtime check (**expo-device's `isDevice`** flag), or wrapping SE key generation in a try/catch that falls back gracefully. Flag your simulator builds clearly in development so you never accidentally test security-critical paths against the fake implementation.

The only way to properly test the full security model is to use real SE keys, real biometrics, and real attestation and load the app onto a physical iPhone via EAS Build or Xcode.

App Demo

We’ll now walkthrough a demo of the application running on iOS device.

[embed]https://youtu.be/IxY8_hNG6kk

Final Code

If you’d like to try the code out yourself, take a look at https://github.com/berachain/guides/tree/main/apps/evm-wallet:

[embed]guides/apps/evm-wallet at main · berachain/guides A demonstration of different contracts, languages, and libraries that work with Berachain EVM. - guides/apps/evm-wallet…github.com

Next Steps

A few natural directions from here:

WalletConnect integration — letting the wallet connect to dApps via QR code is the feature that makes it actually useful day-to-day. The **@walletconnect/web3wallet** SDK handles the session management; the tricky part is routing signing requests back through your SE-wrapped key pipeline.

Transaction history — querying an indexer or a block explorer API gives you a proper activity feed without running your own node.

Push notifications for incoming transactions — requires a backend listener (or a webhook from a web service), but transforms the app from a read/sign tool into something that feels live.

If you want to build more on Berachain and see more examples. Take a look at our ***Berachain GitHub Guides Repo*** for a wide variety of implementations that include NextJS, Hardhat, Viem, Foundry, and more.

❤️ Don’t forget to show some love for this article 👏🏼.


메타데이터
post_id
55fbb221ad0d
slug
building-a-mobile-evm-wallet-with-react-native-55fbb221ad0d
url
https://medium.com/@codingwithmanny/building-a-mobile-evm-wallet-with-react-native-55fbb221ad0d
canonical_url
https://medium.com/@codingwithmanny/building-a-mobile-evm-wallet-with-react-native-55fbb221ad0d
author_url
https://medium.com/@codingwithmanny
status
ok
fetched_at
2026-06-12 07:40:50