Open-source project
novasamatech/parity-signer avatar
novasamatech/parity-signer

Polkadot Vault: an air-gapped wallet on a phone with the radios off

Air-gapped crypto wallet.

611 stars171 forksRustGPL-3.0

At a glance

What is it?
Polkadot Vault is a mobile app that turns a smartphone into cold storage for Substrate accounts, exchanging data with the outside world only as QR codes. The security model depends on a step most users will find inconvenient, which is physically disabling the phone's networking, and the app is built as a Rust core with Swift and Kotlin shells around it.
Who is it for?
Polkadot Vault suits someone holding Substrate, Polkadot or Kusama accounts who wants the keys on a device with no network stack at all, and who is prepared to swap that phone in and out of airplane mode for every transaction. It is a poor fit for daily use on a connected device, since the entire premise is that connectivity must be off, and a poor fit for hardware wallet users who expect the phone to be a companion to another signer rather than the signer itself.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 18 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The security model starts with switching off the radios

Polkadot Vault is a mobile application that allows any smartphone to act as an air-gapped crypto wallet, which is also known as cold storage. You can create accounts in Substrate-based networks, sign messages and transactions, and transfer funds to and from those accounts, with no sort of connectivity enabled on the device.

The catch is stated without hedging. You must turn off, or physically remove, the smartphone's Wifi, mobile network and Bluetooth, to ensure that the phone holding the accounts is not exposed to any online threat. Switching to airplane mode suffices in many cases.

That requirement is the whole design, and it is what makes the rest of the app possible. Any data transfer from or to the app happens using QR code, so the most sensitive piece of information, the private keys, never leave the phone. There is no server, no account and no sync in the background. The app can hold any Substrate account, which includes the Polkadot and Kusama networks.

It is available for both iOS and Android, with public builds on the App Store, Google Play and the GitHub releases page. The official site is at vault.novasama.io, and the end user documentation is hosted as a wiki with pages covering installing on a new phone, creating keys, upgrading and adding new networks.

What the app actually lets you do

The feature list is short and specific.

You can generate and store multiple private keys, parse and sign transactions, and use derived keys to have multiple addresses with a single seed phrase. That last one matters in practice, because it is the difference between one address per key and a handful of addresses from one backup.

There is backup and restore for accounts, and an activity log that the documentation says is there to detect unauthorized access. That is a different threat model from the usual wallet one: the assumption is that someone with physical access to the phone might try to use it, and the log is what you would look at afterwards.

Metadata can be updated without going online, which is the part that keeps the air gap intact. New networks can be added, again without a network connection, because the network definitions travel as QR codes rather than being fetched.

The companion pieces are separate applications. Signer Companion is a web extension to inject keys from Signer and sign transactions through the browser, which is what makes a phone-only setup usable with a desktop wallet. The Metadata Portal serves QR codes with the latest metadata. BananaSplit is a tool to split your seed phrase for maximum security. There is also a legacy branch, the last public release with React Native, for anyone who needs the older native implementation.

A Rust core with Swift and Kotlin shells

Vault is a native app for iOS and Android. The native user interfaces are written in Swift and Kotlin, and they sit on top of a universal Rust core library which implements all the logic. The consequence of that arrangement is that the security-relevant code is in one place, written once, and reviewed once, instead of existing in two platform implementations.

The repository layout follows from that. There is an `android` directory for the Android project, which builds with Android Studio automatically, an `ios` project folder with its own build process, a `rust` folder holding the backend code, a `docker` directory with files for CI on GitLab, a `docs` directory with the official documentation that is built and published on each commit, and a `scripts` directory with mostly releasing scripts plus the `./build.sh` required for building the iOS library.

The readme says that since most of the application logic is concentrated in the `rust` folder, it makes sense to review it separately, and the folder list that follows is unusually detailed for a readme. It also marks certain folders as important for the application logic with an emoji, which the readme explains in a note. The three folders carrying that marker are `db_handling`, which holds all database related operations for Vault and the `generate_message` tool and where most of the business logic sits, `navigator`, where the app navigation is realised in Rust in order to unify behaviour across platforms, and `signer`, the FFI interface crate that generates bindings bridging the native code and the Rust backend.

Three binaries in the Rust folder

The Rust folder contains three actual endpoints, and each has a distinct job.

`signer` is the source of the library used by Vault itself. `generate_message` is the tool used to update the Vault repository with new built-in network information and to generate over-the-air-gap updates, which is the machinery behind the offline metadata updates and the ability to add networks. And `qr_reader_pc` is a minimalistic app to parse QR codes, which the project says it had to write since there was no reasonably working alternative.

The supporting sub-folders show the shape of the data flow. The `parser` parses signable transactions and is internal logic for `transaction_parsing`, but it could be used as a standalone library for the same purpose. `transaction_parsing` is the high-level parser for all QR payloads sent into Vault, and `transaction_signing` holds all the operations that can be performed once the user accepts a parsed payload.

The QR side is split three ways. `qrcode_static` generates the static QR codes used all over the workspace, `qrcode_rtx` is a multiframe erasure-coded payload generator for the signer update QR animation, and `qr_reader_phone` handles parsing of QR payloads inside the app. The desktop reader, `qr_reader_pc`, is also capable of parsing multiframe payloads, though the readme is honest that in practice this is not feasible because of the low performance of a PC webcam. That is a good example of a limitation stated plainly rather than buried.

`printing_balance` is a small library for rendering token amounts with proper units, and `constants`, `defaults`, `definitions` and `files` hold the shared values, built-in and test data, workspace-wide objects, and the test and generation files used by the build and update processes.

Building it means Rust, a matching uniffi, and opencv

The build process is documented in four numbered steps, and the first one sets the tone: make sure you have the latest Rust installed, because nothing will work without Rust. If you hit errors like `cargo: feature X is required`, the most likely explanation is an old Rust version, fixed by running `rustup update stable`.

The second step is the binding generator. You install `uniffi-bindgen`, and the version has to match the version of the `uniffi` crates specified in the project, which the readme says is currently `0.22.0`:

bash
   cargo install uniffi_bindgen --version 0.22.0

The third step is ensuring the opencv crate dependencies are in place, and the fourth is iOS, where Xcode is assumed to be present already if you are reading that part.

The version pinning is the part worth internalising. The Swift and Kotlin shells talk to the Rust core through bindings generated by uniffi, and a mismatched generator produces bindings that do not line up with the core. For a contributor working on a single platform, that means the toolchain version is part of the contract rather than a convenience, and the mismatch shows up as confusing compile errors rather than a clean failure.

The release history also shows a testing process: the repository carries a `RELEASE_TESTING_GUIDELINES.md` file at the root, and the `scripts` directory holds mostly releasing scripts, which suggests releases are a scripted and documented procedure rather than an ad hoc build.

Licence, releases and where the code sits

The project is licensed GPL-3.0, with the licence file at the root of the repository. For an application that most users install as a binary from an app store, the practical effect is on redistribution rather than use.

The release tags tell you about the cadence and about the platforms. Version 7.2.0 and 7.1.0 are both Android builds tagged on 2025-12-16, minutes apart, and version 7.0.0 was tagged on 2025-05-05. The last push was on 2026-10-05 on the default branch `master`, and the repository is not archived, so work continues even though the newest tags are from the end of 2025. The official downloads are on the App Store, Google Play and the GitHub releases page.

Other files at the root give the shape of the project. There is a `CODEOWNERS` file and a `pull_request_template.md`, so the repository is set up for outside contributions. There is a `Gemfile` and `Gemfile.lock`, which is unusual in a Rust and native mobile project and usually points at documentation or linting tooling. There are `build.gradle`, `settings.gradle`, `gradle.properties`, `gradlew` and `gradlew.bat` for the Android side, and a `.buckconfig` for Buck, alongside `.spellcheck` and `.editorconfig` for the text and formatting rules. A `.watchmanconfig` sits next to those, which is the file watcher used on macOS during development.

The whole design, in the end, trades convenience for isolation. The phone is deliberately useless for anything else, and the QR code is the only bridge to the machine that actually holds your keys in a normal wallet.

Editorial conclusion

Polkadot Vault suits someone holding Substrate, Polkadot or Kusama accounts who wants the keys on a device with no network stack at all, and who is prepared to swap that phone in and out of airplane mode for every transaction. It is a poor fit for daily use on a connected device, since the entire premise is that connectivity must be off, and a poor fit for hardware wallet users who expect the phone to be a companion to another signer rather than the signer itself. Before you install, read the end user documentation for installing on a new phone, and check that the release you pick has a build for your platform, since the recent tags are Android builds and the older public releases live on a different branch.

Frequently asked questions

What is Polkadot Vault and how is it meant to be used?

It is a mobile application that lets any smartphone act as an air-gapped crypto wallet, also known as cold storage. You create accounts in Substrate-based networks, sign messages and transactions, and transfer funds, with all data exchange happening as QR codes so the private keys never leave the phone.

Do I have to disable networking on the phone running Polkadot Vault?

Yes. The documentation says you must turn off, or physically remove, the smartphone's Wifi, mobile network and Bluetooth so the device is not exposed to online threats, and that switching to airplane mode suffices in many cases.

Which networks can Polkadot Vault hold accounts for?

Any Substrate account, which includes the Polkadot and Kusama networks. New networks can be added without going online, because the network information travels as QR codes generated by the `generate_message` tool.

How do I sign a transaction from a desktop wallet?

With the Signer Companion web extension, which injects keys from Signer and signs transactions through the browser. The application itself stays off the network and only exchanges QR codes with the other device.

What is needed to build Polkadot Vault from source?

The latest stable Rust toolchain, a `uniffi-bindgen` version matching the `uniffi` crates in the project, which is currently 0.22.0, the opencv crate dependencies, and Xcode for the iOS build. The Rust core lives in the `rust` folder and the native shells in `ios` and `android`.

Official sources

  1. License: GPL-3.0
  2. novasamatech/parity-signer on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/novasamatech-parity-signer.svg)](https://hysenlabs.com/projects/novasamatech-parity-signer)

Was this useful?