Download the wallet

Pick your device. The wallet holds your keys on that device, and you can use it in a browser right now while the apps are on their way.

Windows.exe installer Coming soon
macOS.dmg, Apple or Intel Coming soon
LinuxAppImage or .deb Coming soon
Android.apk, direct download

Not on Google Play yet. Installing this build means allowing an install from outside the store, and if you later install the Play version you have to uninstall this one first, which erases the wallet.

iOSApp Store Coming soon
ChromeExtension Coming soon
Open the web wallet Runs in your browser. Nothing to install. Available now

Android is the first app with a public release, and it is the direct download rather than a store listing. The other buttons go live as each one ships. The web wallet is live now, and it is the same wallet.

The details

Everything below is reference: what each format is, how updates work, and how to check a download once the builds are public. You do not need any of it to use the web wallet.

What runs where

SystemFormatsUpdates itself?
Windows 10/11, 64-bit Intel or AMD
Windows 11 on ARM
Installer (.exe, one per processor), portable .zip Installer: yes
Zip: no, download the new one
macOS, Apple silicon
macOS, Intel
.dmg, .zip Yes, for both
Linux, 64-bit Intel or AMD
Linux, 64-bit ARM
.AppImage, .deb Yes, for both
Debian package: asks for admin rights, see below
Android 8.0 and later Google Play, or a direct .apk Play: yes, through Play
Direct: no, it tells you and you download the new one

Which Windows installer

There are two, and the name says which processor each is for:

  • -x64 for Intel and AMD machines. This is almost certainly the one you want.
  • -arm64 for Windows on ARM, such as a Snapdragon-based Surface.

If you are not sure, Windows tells you: Settings, then System, then About, under "System type". Updates after that always fetch the build that matches your machine.

The Debian package updates itself, and asks for your password

Both Linux formats update themselves, but not in the same way. The AppImage is a single file the wallet can replace on its own. The .deb is a system package, so installing a new version means running the system package manager, and your desktop will ask you for administrator rights before it does. That prompt is expected: it comes from the operating system, not from the wallet, and it appears once per update.

Before that prompt ever appears, the wallet has already checked the download against the maintainer's signature (the same signature described below). It will not ask you to authorise installing anything it could not verify.

If you would rather never see an administrator prompt, use the AppImage.

Why there is no 32-bit build

Three of these are not our decision, and one is:

  • 32-bit macOS: impossible. Apple removed support for 32-bit apps in macOS Catalina in 2019, and no toolchain to build one exists.
  • 32-bit Linux: impossible. The framework the wallet is built on dropped 32-bit Linux in 2019. Shipping it would mean freezing the wallet on a seven-year-old browser engine, which for a wallet is a security floor we will not accept.
  • 32-bit ARM Windows: impossible. It never existed as a supported target.
  • 32-bit Windows: possible, and we have chosen not to. The only operating system that can run it is 32-bit Windows 10, which left Microsoft support on 14 October 2025. A wallet whose entire audience is running an unpatched OS is not a coverage win.

32-bit ARM Linux (older Raspberry Pi-class boards) is buildable and is not ruled out; there is simply no evidenced demand yet. If you want it, say so.

A store install and a direct install keep separate wallets

The desktop wallet is heading for the app stores as well as this page: the Microsoft Store on Windows, the Mac App Store on macOS, and the Snap Store on Linux. The app is the same either way. What differs is where it is allowed to keep its files, and that has one consequence worth knowing before you install both.

A store build and a build from this page do not share a wallet. Every store puts an app's files in storage of its own: Apple's sandbox, the Microsoft Store's per-package storage, and a Snap's own home directory. A wallet you create in one is simply not visible to the other. Installing both does not give you the same wallet twice, it gives you two empty ones.

This is not something the app can detect and warn you about, and we are not going to pretend otherwise: a sandboxed build largely cannot see that the other install is there. So it is stated here instead.

To move a wallet from one to the other, use the wallet's own encrypted backup. Export it from the install you have, then import it into the install you want. That is the supported path, it works between any two installs on any operating system, and it does not depend on the two being able to see each other. As always, your recovery phrase brings a wallet back from nothing at all.

Android: two ways to get it, and they do not mix

The Android app is the same wallet, wrapped so it can be installed on a phone. You can get it from Google Play, or download the .apk from us directly. The app is identical either way. What differs is who signed it, and that turns out to matter more than it sounds.

Android will not let you swap one for the other in place. A phone accepts an update only if it carries the same signature as the app already installed, and these two carry different ones. Moving from the Play install to the direct one, or back, means uninstalling first.

Uninstalling the app erases the wallet on that phone. Your keys live in storage that Android deletes with the app, and there is no cloud backup to fall back on, on purpose. Have your recovery phrase written down and in your hand before you switch. Reinstalling and importing that phrase brings everything back; nothing else will.

If you have no reason to prefer one, take the Play version: it updates itself, and the phone will not ask you to allow installing from an unknown source. The direct download exists for people who would rather not involve Google in it, and for the case where the Play listing is unavailable.

Checking the direct download

The direct .apk is signed with a key we hold, and its certificate fingerprint is this:

4B:5D:E0:91:CF:39:97:31:06:11:B8:46:8B:67:79:DC:
72:F5:8A:2A:94:0E:53:4F:1E:0A:59:AD:D8:25:9E:28

Check a downloaded file against it with the apksigner tool from the Android SDK:

apksigner verify --print-certs xchain-wallet-vX.Y.Z.apk

The value printed as SHA-256 digest should match, character for character. The .apk is also listed in the release hash manifest described below, like every other file we publish.

Compare against the copy in SECURITY.md rather than the one on this page. A fingerprint printed on the same website that served you the file proves nothing if that website is the thing that went wrong; the point of checking is that the two copies come from different places.

A Play install has a different fingerprint, and that is normal. Google re-signs what it distributes and serves a build cut down to your specific phone, so a Play install cannot be checked against the value above or against our manifest at all. The direct download is the only Android build anyone can verify against what we published.

Updates for the direct download

The direct app does not update itself. Once a day at most, it asks a file on our download server what the newest version number is, and if yours is older it says so in a banner. That is the whole mechanism: it never downloads anything on its own, it never acts on anything the file says beyond that one version number, and you can switch the check off in Settings, then About.

There is also no way for us to pull a bad direct release back. Android refuses to install an older version over a newer one, and forcing it would mean an uninstall, which erases the wallet. If a direct release ever needs replacing we publish a signed notice saying so and a fixed higher version, and that is the entire remedy available to us.

One difference from the desktop build

Both Android builds come from the same file, signed twice, which is what lets us promise they are the same code. That file is the one prepared for the store, so a surface or two the desktop app shows is not compiled into either Android build. Everything to do with holding, sending, and signing is present in both.

Checking what you downloaded

Every release publishes RELEASE_HASHES/<version>.txt and a detached GPG signature next to it. The manifest lists the SHA-256 of every file in the release, and the signature proves the maintainer produced that list.

This matters most on Linux, where the AppImage and the .deb carry no operating-system signature of their own: the manifest is the only thing standing between you and whatever the download host served. On Windows and macOS the operating system checks the code signature too, so you get both.

The full step-by-step is in Verifying a release, and the fingerprint to check the signing key against is on our security page. It is worth doing once even if you never do it again.

Windows may warn you the first time

A newly issued signing identity starts with no reputation, so Windows SmartScreen may show "Windows protected your PC" for early downloads even though the installer is correctly signed. That warning fades as more people install. If you want certainty rather than reassurance, check the hash manifest above.

What an update check sends

When the wallet checks for updates it makes one ordinary web request to our download server. That request carries:

  • Your IP address, as any web request does.
  • A user agent of electron-builder. It is that literal string: it does not include your wallet version, your operating system version, or anything about your machine.
  • Your operating system and processor architecture, disclosed by which file is requested rather than by any header: a Mac asks for stable-mac.yml, a 64-bit ARM Linux machine for stable-linux-arm64.yml.
  • A cache-busting number derived from your device's clock, appended to the request so an intermediate cache cannot serve a stale answer.

Notably, the check does not tell us which version you are running. The wallet downloads the list of the latest release and compares it against itself on your device; the comparison never leaves your machine. We learn that somebody at your IP, on that OS and architecture, checked for updates.

There is no account and no analytics SDK. There is also no identifier that persists between checks, and that one took work rather than luck: the update library we build on sends a random identifier it creates on first run and then reuses forever, which would have let our download server count installs and follow one as its address changed. The wallet replaces that value with a fixed all-zero placeholder before any request leaves your device, so every install sends the same meaningless value. This paragraph is written from an actual capture of the request rather than from reading our own code; the capture is published in the wallet repository at docs/update-check-capture.json and is regenerated by tooling, so if the request ever changes, this page is wrong in a way that is checkable.

The wallet's full privacy policy is here.

Building it yourself

The desktop wallet is open source under the AGPL. The Linux build is reproducible: build it in the pinned container described in packages/desktop/REPRODUCIBLE_BUILDS.md and you should get a byte-identical artifact to ours before signing. macOS and Windows builds publish maintainer-produced hashes rather than independently reproducible ones, and that document says exactly why.

The Android build is not reproducible either, and we would rather say so than let the word cover it. What the direct .apk has instead is the signed hash manifest and the certificate fingerprint above, which tell you the file is the one we published; they do not let you rebuild it and confirm the source matches. Making the Android build reproducible is real work we have not done yet.