AirWallet Docs

Updates, downloads and outside code

How to check that a download is the real one, how AirWallet controls the outside code it is built from, and how to update both devices safely.

A wallet can be attacked before you ever open it: through a swapped download, a tampered library, or a script slipped into a page. This page covers what AirWallet does about each, and what you can check yourself.

Check a download before you open it

Every release comes with a list of its files' SHA-256 checksums, SHA256SUMS.txt, signed with AirWallet's release key. Four files go with the downloads:

  • SHA256SUMS.txt, the list
  • SHA256SUMS.txt.sig, its signature
  • RELEASE-SIGNING-KEY.txt, the public key
  • VERIFY.txt, these same steps

You need only ssh-keygen, which macOS, Linux and Windows 10 and 11 already have. Put the 4 files next to your download, then follow the 3 steps below.

1. Check the key

The release key's fingerprint is:

SHA256:SV031wxY3OKk8aYTY4a6b7UYa80onuXiDi0tFobgOFE

Also compare it with what the person who gave you the download told you some other way: in person, on a call, or in another app. A swapped file could come with a swapped key.

2. Check the list's signature

On a Mac or Linux, in Terminal:

ssh-keygen -Y verify -f RELEASE-SIGNING-KEY.txt -I airwallet-release -n airwallet-release -s SHA256SUMS.txt.sig < SHA256SUMS.txt

On Windows, in PowerShell:

Get-Content SHA256SUMS.txt -Raw | ssh-keygen -Y verify -f RELEASE-SIGNING-KEY.txt -I airwallet-release -n airwallet-release -s SHA256SUMS.txt.sig

It must say Good "airwallet-release" signature for airwallet-release with ED25519 key, followed by the fingerprint above.

3. Check your file is on the list

On a Mac or Linux:

shasum -a 256 -c SHA256SUMS.txt --ignore-missing

It must say OK next to your file. On Windows, run certutil -hashfile <the file> SHA256, then find that number in SHA256SUMS.txt.

What the signing tool refuses

The release tool signs with an Ed25519 key through ssh-keygen -Y sign, under the name airwallet-release, and checks its own signature before it writes VERIFY.txt. It refuses to sign when:

  • the key does not match the published RELEASE-SIGNING-KEY.txt
  • any file in the list is empty
  • any file is more than 2 days older than the newest one, which usually means it was left over from an older build

What the operating systems check

The operating systems' own signatures help less for now:

  • Mac: the app is sealed with its signature, but Apple has not notarized it yet
  • Windows: the .exe is not code-signed yet
  • Android: APKs are signed, and Android installs an update over the old app only if it has the same key

On Android, if the system asks you to uninstall the old app first, the new file is not ours: stop. See Install for the first-open steps on each system.

Builds are not reproducible yet

You cannot yet rebuild AirWallet from its source and get byte-identical files. The signed checksum list proves a file is the one that was signed, but not that it matches the published source. Reproducible builds and an F-Droid listing are on the to-do list.

Every piece of outside code is fingerprinted

AirWallet keeps one list of all the outside code its apps are built from, third_party.json in the source. Each entry records what the code is, its license, where it comes from and a fingerprint. A test, tests/test_third_party.py, checks every fingerprint. A new version, a different dependency or an edited file fails the test until a person has reviewed it and updated the list.

Outside codeWhat it is for
Google's Brotli decoder, at a pinned commit, unchangedUnpacking the Monero and Zcash engines
monero-ts 0.11.20 and its npm packagesMonero's own wallet library, as WebAssembly
Our rebuild of monero-ts for older web enginesMonero in the Android apps, from Android System WebView 74
The Zcash engine's crates (librustzcash, orchard, sapling-crypto and others), one of them patchedThe Zcash wallet, as WebAssembly
The Zcash prover's crates (Zakura)Zcash's shielded proofs
The Monero vanity engine's crates, with a vendored curve25519-dalekThe desktop's Monero vanity search
Python packages from requirements.txt (PyNaCl, base58 and the rest)The desktop apps' Python code
Python runtimes (python-build-standalone, CPython 3.12.15)The Python inside each desktop app
esbuildBundling the JavaScript (build tool, not shipped)
wasi-sdk, wasm-bindgen, binaryenBuilding the Zcash WebAssembly (build tools, not shipped)
r8 and apksig, from Google's MavenBuilding and signing the Android APKs (build tools, not shipped)
The AppImage runtime (AppImage/type2-runtime)The start of every Linux AppImage

Each is also checked where it is installed, and the test makes sure every crate, npm package and Python requirement keeps its hash:

  • every downloaded tool has a pinned SHA-256, checked before the download is used
  • JavaScript packages come from a lockfile with each package's hash (npm ci, with install scripts turned off)
  • Rust crates are built with cargo --locked, so each crate's checksum is checked
  • Python packages are installed with --require-hashes, so a changed, missing or unpinned file stops the build

Nothing is downloaded and run later

Every engine ships inside the package, and the apps never fetch code while they run. The one thing fetched later is data. The first time you spend a Zcash Sapling coin or pay a Sapling address, the online app downloads Zcash's Sapling parameters, and checks their SHA-256 before it keeps them.

Pages run only their own scripts

Each AirWallet page tells the web engine exactly which scripts may run, by their SHA-256 fingerprints, through a Content-Security-Policy without unsafe-inline. Text that reaches the page any other way can never run as code. That includes a token's name, a transaction memo and an address book entry.

WhereHow the policy is set
Android appsWritten into the page when it is built
Desktop appsSent with the page by the app's local server, which fingerprints the page's scripts when it starts
airwallet.tech/onlineSent by the web server. The page's one inline script is listed by its fingerprint, and the Monero and Zcash engines are separate files from the same site.
Chrome extensionOnly the extension's own script files run (script-src 'self'), with no inline script at all

Web engines older than Chrome 97 can run WebAssembly only if the policy also allows unsafe-eval. AirWallet's Monero and Zcash engines are WebAssembly, so on those old engines, and only there, the page's policy includes it. AirWallet's code never evaluates text as code, and the list of scripts allowed to run stays the same.

AirWallet Online changes when the site changes

AirWallet Online is watch-only. It never holds a key and sends nothing to airwallet.tech. But the page itself comes from airwallet.tech, so a change to the site changes the page. If you want a copy that never changes under you, open its Settings, select Save this page, and open the saved file from your disk. The saved copy works for Bitcoin, Ethereum and Solana. Monero's and Zcash's engines are separate files, so they do not come with it.

Updating

You do not have to update both devices together. An offline device can stay on the version you installed while your everyday copy updates, and the other way round:

  • newer copies keep making codes that older offline devices read, and every copy reads the codes and answers of every older one
  • a newer copy may add something an older one cannot do; that one code says it was "made by a newer version of AirWallet", and everything else keeps working
  • your offline device's watch code tells the everyday copy which version it runs; show it again after you update the offline device

Each release is kept and tested against later ones in both directions: the newer copy signing with the older one and the older with the newer, for Bitcoin, Ethereum and Solana. Monero and Zcash codes follow those coins' own wallet formats, so after one of their network upgrades both devices need the update.

Two things do need an update:

  • a coin's network upgrade, when an older copy cannot make valid transactions under the new rules. AirWallet says so, and only that coin stops until you update.
  • data or a backup saved by a newer version. An older copy will not open it, rather than misread it.

The everyday device

Install the new version over the old one. Your wallets, settings and app lock stay, because they live in the device's storage, not inside the app. On a Mac, for example, they are in ~/Library/Application Support/AirWallet.

For the Chrome extension, replace the contents of its folder with the new version's, then select the reload button (↻) on its card in chrome://extensions. Its data stays. Removing the extension from Chrome deletes its data, so keep your recovery phrases.

The offline device

The offline device cannot download anything, so you carry the update over yourself:

  1. Download the update on your online computer and check it there, as above. The app has no signature check of its own for update files yet.
  2. Copy it to the offline device by USB cable or SD card. Airplane mode can stay on.
  3. Install it over the old version.

Network upgrades

Sometimes a coin's network changes its rules, and an older signer can no longer make valid transactions. Zcash's NU7 upgrade is due around November 5, 2026. Monero's FCMP++ upgrade has no date yet. When a network moves to rules your copy does not know, AirWallet refuses to send and asks you to update both devices. See Clocks, old phones and other edge cases.

AirWallet documentation · updated 2026-10-15 · airwallet.tech