Architecture
Five choices that make a private wallet practical on a phone. Each one is a real trade, drawn rather than asserted.
Every block gets a compact filter — a small summary that answers “might this block touch one of your scripts?” Winnow checks that on the phone. Only a hit costs a full block download, and nobody is ever told which scripts it asked about.
Every block · always
the same public filter any compact-filter client can request
On a hit only · rare
only when a filter matches
The asymmetry is the design. A small public filter for each block, a whole block only on a match, and no query that names an address — so there is nothing for a wallet server to log, because there is no wallet server.
Filters describe blocks, so a payment would normally be invisible until it confirms. While the Receive screen is open — exactly when you are expecting money — Winnow subscribes to full relay traffic and matches locally, then closes the window when you leave.
Asking for everything is what keeps it private — asking for one address is what would give you away. The cost is bandwidth, and it is bounded by a screen you actually have open.
Recovering an old wallet privately would mean re-downloading years of filters. Winnow refuses that: a new wallet scans forward from the day it was made, and an imported one arrives with its own history plus the height it was true as of.
Import cost is proportional to how stale the bundle is, not how old the wallet is. A bundle exported at the tip is a JSON parse and a zero-length scan — and it's why Winnow writes one of its own.
Elena and Mateo hold the family reserve together — a 2-of-2 MuSig2 vault, coordinated over PSBTs with no wallet server in the middle. Two rounds, public nonces then partial signatures, collapse into a single Schnorr signature.
Each phone publishes a public nonce. The secret halves stay in the signing screen and never persist — leaving before round 2 abandons the session.
Elena and Mateo each sign the same sighash, producing a partial signature that is verified before it is attached. Signing zeroes the secret nonce.
The two partials combine, and the result is checked against the vault's aggregate key before it is trusted.
64 bytes · P2TR key-path
Identical in form to an ordinary single-signature spend. Watchers cannot tell a vault from an everyday wallet.
Both-of-two costs the chain one signature, so the on-chain witness shape and fee are those of an everyday spend. That is a statement about the chain only — coordination between cosigners and network-level privacy are separate matters. The k-of-n vault is the honest opposite: it uses a script path, which is visibly multisig — a cost paid deliberately for “k of us, and nobody holds an escape hatch.”
A peer can lie by leaving your transaction out of a filter. You cannot prove which peer lied — but you can notice when they disagree. Winnow asks up to three of them for the same filter checkpoint and compares those answers before trusting any of them.
Among checkpoint answers a strict majority wins, and the odd peer out is dropped and replaced. When two disagree with no majority the lie is unattributable, so Winnow drops all the queried peers and re-dials rather than guess. This majority rule is the checkpoint comparison specifically — it does not govern every filter-header batch.
Detection, not proof — and not operator independence. Peers are dialled by whichever candidates answer fastest, so nothing yet stops one operator supplying more than one slot; pinning slots by source is planned, not shipped. What ships is the comparison and the refusal to proceed on a tie — and a fully eclipsed phone can still be told one coordinated lie.