Building a Light Wallet
How Cake Wallet and MyMonero work: embedded wallet2 vs a light-wallet server, view-key scanning and view tags, and the security trade-offs of each.
Every Monero wallet you've used on a phone — Cake Wallet, Monero.com, MyMonero — had to solve the same hard problem: how do you find your money on a chain you can't fully scan? A laptop with a local node can churn through every block, but a phone on a cellular connection can't realistically download and validate the whole blockchain, then test every output in every transaction against your keys. This lesson is the blueprint for the two real architectures wallet builders use to get around that, and how you'd build your own Cake-style wallet on top of them.
The mobile problem
On Monero, there is no public ledger of "your balance." Outputs are sent to one-time stealth addresses, so the only way to discover which outputs are yours is to scan transactions with your private view key and test each one. That scan is cheap per output but there are hundreds of millions of outputs on chain. A server does this comfortably; a battery-powered phone does not. There are two real approaches to making it work on mobile.
Approach 1 — embed wallet2 on the device
The first approach is to compile the official Monero C++ wallet library — wallet2 — directly into the app and let the phone do real scanning and validation on-device. Cake Wallet does exactly this: it ships Flutter/Dart bindings to the underlying monero C++ library, so the cryptography running on your phone is the same code the reference wallet uses. Monero.com (Cake's sibling app) works the same way.
Crucially, the app still doesn't store the blockchain. It syncs against a remote node — either one the user runs or a public one — pulling down blocks and scanning them locally with the view key. The node is just a data source: it can't see your keys, can't spend, and can't lie to you about transactions because your own wallet2 validates what it receives. This is trustless on the wallet and crypto side. The cost is the first sync: the phone has to fetch and scan a lot of blocks, which is heavier on bandwidth, CPU, and battery, especially when restoring an old seed.
Approach 2 — a Light Wallet Server (LWS)
The second approach offloads the scanning entirely. A Light Wallet Server holds the user's private view key and scans the chain on their behalf, then hands back just that user's outputs. MyMonero pioneered this model; the open-source reference implementation is monero-lws.
The key insight is the split between viewing and spending. The server can find your incoming money because the view key is enough to scan — but it never receives your spend key. When you want to send funds, the client downloads the necessary outputs and decoys, then builds and signs the transaction locally with the spend key, and only the finished, signed transaction goes back to the server to broadcast. The server sees your incoming transactions and amounts, but it cannot spend a cent. (For why view and spend keys are separable like this, see public & private keys.)
How view-key scanning works
Both approaches rely on the same trick — the difference is only where it runs. Each transaction publishes a public key R. To test whether an output belongs to you, you combine your private view key a with R to derive a shared secret, Hs(a*R). From that secret you can reconstruct the one-time public key the sender would have used if the output were yours; if it matches the output on chain, it's yours, and the same secret lets you recover the amount.
Doing that full check on every output is expensive. View tags fix this: a view tag is a 1-byte hint the sender attaches to each output, derived from the same shared secret. A scanner computes the expected tag first and, if it doesn't match, skips the output without doing the rest of the work. Since a random output matches your tag only about 1 in 256 times, view tags let a scanner discard the vast majority of outputs almost for free — a major speedup that makes light wallets and fast restores practical.
The LWS API surface
A MyMonero-style LWS (and monero-lws) exposes a small, predictable set of endpoints:
login— register the account (address + view key) so the server begins scanning for it.get_address_info— balances, scan height, and locked/unlocked totals.get_address_txs— the user's transaction history.get_unspent_outs— the spendable outputs the client needs as inputs when building a transaction.get_random_outs— random outputs from the chain to use as decoys (ring members) so the real input is hidden.import_request— kick off a full rescan from an earlier height (e.g. when restoring).submit_raw_tx— the client sends its locally signed transaction for the server to relay to the network.
Notice the shape: every endpoint either reports view-key data or relays an already-signed transaction. Nothing in the API can move funds, because signing never happens server-side.
Trade-offs
- Embedded wallet2: full validation and maximum trustlessness; the phone verifies everything itself. Costs more bandwidth, CPU, and sync time, especially on first restore.
- LWS: fast and light — the server does the heavy scanning. The trade-off is privacy: because it holds your view key, the server can see your incoming transactions and amounts. It still cannot spend and cannot steal, since it never holds the spend key. Spending is always client-side.
Many wallets offer both, letting the user choose convenience or maximal trustlessness per their threat model.
A caution worth passing on to your users: the LWS model is fine to build on and to understand, but a pure web wallet that runs in the browser — MyMonero being the classic example — is generally discouraged for holding real funds. A web app re-downloads its code from a server on every visit, so a single compromise of that server can ship key-stealing code straight to the user; and the hosted light-wallet server sees the user's view key and full incoming history. If you ship a light wallet, prefer a native installed app (downloaded and verified once) over a web page, let users point at their own node or LWS, and steer anyone holding meaningful amounts toward a fuller wallet or hardware device.
Key and seed management on the device
Whichever architecture you pick, the wallet app owns the same responsibilities. It generates or restores the 25-word mnemonic seed, derives the view and spend keys from it, and stores those keys in the platform's secure storage (the iOS Keychain or Android Keystore), ideally behind a PIN or biometric. It should let the user pick which node (or LWS) to connect to, so privacy-conscious users can point at their own infrastructure. The spend key must never leave the device.
Get these pieces right — view-key scanning with view tags, a remote node or LWS for data, and client-side signing with keys locked in secure storage — and you have the full skeleton of a Cake-style mobile wallet.
Created June 30, 2026
Comments
Log in or create a free account to comment.
No comments yet — be the first.