xmrwallet
blog

Blog

Notes on Monero, privacy tech, and boring, dependable code.

Why I built another Monero web wallet

There is no shortage of Monero wallets. So why build one more?

Because most of them ask you to choose between two things I didn't want to choose between: running a full node on my own hardware, or handing my keys to someone else's browser app. The first is honest but heavy — a full node is tens of gigabytes and a multi-day sync before you can see a balance. The second is easy, but "the keys live in a tab" never sat right with me.

xmrwallet-core takes the middle road, and is upfront about what that means. Your seed phrase is yours. The server stores it encrypted (AES-256-GCM, per-wallet data keys wrapped by a master key that never leaves the service environment) and does the heavy lifting: chain scanning, transaction building, signing. Nothing wallet-related runs in your browser — just a static page and an API. That makes restores fast, balances instant after the first scan, and the whole thing auditable: it's a plain TypeScript app you can read in an afternoon and run yourself. The repo is the product.

A few decisions worth explaining:

The server is the wallet. This is a semi-custodial model and I'm not going to pretend otherwise. If you want full self-custody, run your own instance — it's designed for exactly that, and the hosted one exists for people who'd otherwise use something worse.

Restores are a background job, not a progress bar you babysit. Import a seed with an approximate date and it's ready in minutes; leave the height at zero and it scans in the background while the page stays live. New wallets created on the site sync instantly since we record the chain height at birth.

Boring code on purpose. Node.js, Postgres, vanilla JS frontend, zero third-party scripts, a CSP with no exceptions. The exciting part should be Monero, not the wallet software.

It's on stagenet-first development (real coins, zero value, free faucets), with mainnet support in the same build. If you want to poke at it, the quick start in the README takes about ten minutes.

Feedback welcome — the repo is the best place for issues and questions. If it's useful to you, donations keep the lights on.