Secure Mobile Crypto Wallet
Objective
Build a non-custodial mobile wallet tailored for mainstream crypto users in Asian markets, featuring multi-chain account abstraction and biometric key protection. The year was 2018: seed phrases were still the product, exchanges were still the default, and a “wallet for normal people” mostly meant a smaller copy of a desktop UI.
The users we cared about were not traders staring at order books. They were people who needed to hold, send, and receive on more than one chain without becoming key-management experts. Asia was the distribution context — device mix, app-store realities, and the expectation that a fingerprint or face is how you unlock anything that matters.
Non-custodial was a constraint, not a slogan. If we could read the private key in JavaScript, we had already failed.
Architecture Highlights
Hardware keystore integration. Private keys never touch JavaScript memory. Signing is offloaded to the iOS Secure Enclave and the Android Keystore. The React Native layer asks for a signature; the OS prompts biometrics; the key material stays in hardware-backed storage. This is slower to implement than ethers.Wallet in JS. It is also the only design that survives a casual screenshot of the debugger.
Offline transaction signing. Air-gapped QR authorization for a cold-storage mode: an online device builds the unsigned payload, the offline phone signs, the result goes back as a QR. Useful for larger balances and for anyone who does not want the signing device on the same radio as the browser. The UX cost is real; we did not pretend a QR dance is “simple.” We made it an explicit mode.
Lightweight SPV client. Instant block header verification without downloading gigabytes of state. A mobile wallet that waits on a full node it does not run is a custodial app with extra steps. Headers plus proofs kept the phone honest enough for payments without turning the battery into a heater.
Multi-chain account abstraction — 2018 edition. Not the 2024 ERC-4337 meaning. We needed one account surface for more than one network so the user did not hold five seed phrases and five apps. The abstraction was a derivation and UI contract: networks as a list, balances as a sum you can inspect per chain, send flows that refuse to mix gas tokens by accident.
Product constraints
React Native let us ship iOS and Android without two native teams. The native modules for keystore, camera (QR), and biometrics were the actual product. Everything visual was secondary: large tap targets, plain-language errors, no hidden “advanced” screen that contained the only way to export a backup.
Backup was still a phrase, written down, because that is what the chains offered. We invested in the reveal flow (when you see it, why you should not photograph it) rather than inventing a custody model we could not guarantee.
Outcome
The wallet shipped as a non-custodial app with biometric unlock, QR cold signing, and an SPV path that did not require a full node on the device. It was built for Asian mainstream users in 2018, which meant it had to feel like a bank app and behave like a key store. Those two requirements still describe most wallet work. The case is the architecture: keys in hardware, signing off the JS heap, and a client that verifies headers instead of trusting a screenshot of a balance.