Wallets
The Cheshire wallet is an iOS app with a Rust core (wallet-core) that proves, checks
the chain and recovers. The app is a SwiftUI front end over that core. From a shell, the
cheshire-aggregator command line is the reference wallet for developers (wallet, send,
share-submit, wallet-sync, recover).
The app says “private”, not “provably private”; “pending” is not “settled”; and it runs on test coins only.
What the app does
Section titled “What the app does”- Keeps twelve words. The core makes them, the app shows them once, asks two of them
back, and keeps them in the iOS Keychain (this device only). From the words come the
shielded secret
skand a standard Bitcoin key (BIP86) for the coins that fund deposits. The exact derivation is still a proposal: nothing on chain depends on it yet. - Proves on the phone. A payment, a withdrawal or a deposit is one STARK proof made on the device: about a third of a second with many threads in the iOS simulator on a Mac, 0.8–1.2 s on one thread, under 200 MB of memory, about 83 KB. A phone has not been measured; expect it between those figures. Nothing secret leaves the device: a node receives the proof and its public values, never a key or an amount.
- Proves against its own copy of the pool. The wallet rebuilds the pool’s trees from settlements it has checked itself, and asks no node for “the current state”. A node therefore cannot hand it a tagged state to trace its spends.
- Checks the chain itself. It is a light client: it checks Bitcoin’s headers and finds each settlement in its block. See the light client.
- Talks through Tor, by default, so no node or Bitcoin peer sees the phone’s IP address.
- Sends each contribution to a node picked at random from the ones it knows.
- Recovers from the words alone. See seed recovery.
The screens, in short
Section titled “The screens, in short”- Home: one balance, Receive and Pay, the pool’s “heartbeat” (a state word, never a countdown), and the activity list, each item with a “what the chain sees” view.
- Receive has two modes: your payment code (the account number others pay), and a one-time Bitcoin address an exchange or another wallet can pay, which the app moves into the pool for you.
- Pay: a destination, an amount, and a fee level (economy, normal, priority). The proof is made on the phone.
- Wallet: what you hold inside the pool and outside it, with labels and freezing for outside coins.
- Settings: Network (demo or a real pool, the chain, the nodes, Bitcoin peers, Tor), Fees, Recovery (your words), About, and “Help settle”.
Payments in flight
Section titled “Payments in flight”A payment goes through states: sent to a node, accepted into the share chain, fixed into a
batch, and settled in a Bitcoin block. The app learns that a send is done from the chain
itself (one of its nullifier keys appears in the tree). It finds its sends in a node’s list
of all unsettled contributions (GET /payments), so it never has to name the one it
cares about.
If a payment waits because its batch does not yet pay for a settlement, the app says how short the batch is and offers pay more to settle sooner (fees).
Moving coins in
Section titled “Moving coins in”Coins sent to the wallet’s own Bitcoin address are found through compact block filters from Bitcoin peers (no block explorer). The app moves them into the pool as deposits, in standard chips, funding and signing each deposit coin on the phone and sending it to Bitcoin peers through Tor. It asks every configured node for the deposit inbox’s details and goes ahead only if they agree.
Limits, plainly
Section titled “Limits, plainly”- Amounts stay below 2²⁷ sat (about 1.34 BTC) per note. A large balance is several notes.
- The seed scheme is a proposal, and may change before anything real depends on it.
- Not built yet in the app: the backup flow, a privacy check screen, the emergency exit screens, camera scanning, and Lightning.
- Wallets made by the reference command line before 2026-10-01 drew their key from a weak test generator. They are test wallets; treat them as such.