Back to blog
Blog
May 30, 20263 min read

Building Cypher: A Private Web3 Wallet

What I built and learned making crypto transfers private and human-friendly — sending funds with @usernames instead of long, public addresses.

#web3 · #base · #privacy · #wallet · #react-native

Most people assume crypto is anonymous. It isn't. Every transfer you make sits on a public ledger that anyone can read forever. Cypher is my attempt to fix that — a wallet built around the idea that sending money to a friend shouldn't broadcast your entire financial history to the world.

This is the high-level story of what I built and what I learned. I'll go deeper on the specific pieces in later posts.

The problem

Two things make on-chain payments awkward today:

  • No privacy. When you pay someone, anyone can look up your address and see your balance, your history, and who else you've paid. It's like every Venmo transaction being permanently public, tied to your identity.
  • Terrible UX. Addresses look like 0x9f3c...A21b. Copy the wrong character and the money is gone. Nobody wants to share a 42-character string just to get paid.

I wanted a wallet where you could send funds to @alice and have the transfer stay private by default.

What I built

Cypher is a non-custodial mobile wallet on Base L2. Non-custodial means you hold your own keys — there's no company in the middle holding your money. It runs on Base, an Ethereum Layer 2 that keeps fees low enough that small, everyday transfers actually make sense.

The headline feature: you send money to a @username, not a raw address, and the payment lands in a fresh, unlinkable destination each time so observers can't tie it back to the recipient's main wallet.

You can see the project here: Cypher on Devfolio.

The two ideas that make it work

At a glance, Cypher rests on two ideas:

  1. Stealth addresses. Instead of paying someone's public address directly, the sender derives a one-time address that only the recipient can actually spend from. To an outside observer, there's no obvious link between the recipient and the funds. This is what gives the privacy.
  2. Usernames as a friendly layer. A @username maps to the cryptographic material needed to generate those stealth addresses. The complexity stays hidden — the user just picks a name from their contacts and hits send.

I'm keeping this deliberately shallow here. The cryptography behind stealth addresses deserves its own post.

What I learned

  • Privacy and usability constantly pull against each other. Every privacy feature added friction somewhere. The hard part wasn't the crypto — it was making it feel like a normal payments app.
  • The chain choice shapes the product. Base L2 plus Blockscout for reading on-chain data let me keep transfers cheap and fast, which is what made per-transfer privacy practical instead of a luxury.
  • Wallet UX in React Native is its own discipline. Managing keys safely on a device, handling recovery, and signing transactions without leaking anything is a different kind of engineering than building screens.

What's next

Cypher has a few pieces worth unpacking on their own, so I'm going to write them up as separate articles:

  • How ECDH stealth addresses actually work, with the math made approachable.
  • How @username resolution maps a human name to private payment details.
  • On-device key management in a React Native wallet — storage, recovery, and the mistakes to avoid.

If you're building in this space or hiring for it, my resume and LinkedIn are the best ways to start a conversation. More soon.