Skip to content

Repository files navigation

Winnow

A Bitcoin wallet for iOS with on-device compact-filter matching, written in Swift.

Download on the App Store — pre-release builds ship through TestFlight. Mainnet by default; signet is one Advanced-mode toggle away. The broader beta is planned for 0.9; see the release roadmap.

  • Pure P2P by default. The read side is BIP157/158 compact block filters served by full-node peers — the wallet does not send its watch list to a wallet-history server. Peers still observe requests, relay traffic and connection metadata. Bounded mempool windows (short full-relay subscriptions while the Receive or Send screen is open) give 0-conf payment detection and propagation tracking without any server. Read how it works.
  • Taproot today. Current receiving uses P2TR (BIP86), with no ECDSA signing path. The planned 0.7 P2WSH Safe is a separate, opt-in addition.
  • Pay people and share control. Save a public payment card or Bitcoin address. From Wallet, create shared savings with a threshold such as 2-of-3: any two keys can spend while one is unavailable. A 1-of-n policy permits one key to spend. Cards carry public keys only.
  • Require another signing device. Advanced mode offers MuSig2 accounts where every key must participate. The app journey uses Bitcoin Core 31.1 as the second signer, confirms one Taproot key-path signature, and restores the account from a backup. Hardware-wallet compatibility needs its own test. Compare the two signing journeys and their limits.
  • Bitcoin cryptography: swift-secp256k1 (Bitcoin Core's libsecp256k1), pinned; the only third-party dependency. The embedded Tor client shipped in 0.6 through 0.7.0 was removed in 0.7.1 (its source is kept on the archive/tor-0.7.0 branch); Tor and I2P are on the roadmap.
  • Warned explorer links — choose mempool.space or a custom Esplora website; Winnow opens it only after a tap and privacy warning, never as a wallet backend.

Release roadmap

The public roadmap keeps planned work separate from current features. Each milestone describes the user outcome, the journeys that must pass, and unresolved work. Milestones are targets, not shipped capabilities or promised dates.

Layout

The app, Bitcoin implementation, CLI, fuzz harness, debugging tools and website live in this repository. The app and all development tools use one root Swift package and dependency lockfile. There is one release version and one source revision.

The app owns the user flows. WalletCore contains Bitcoin primitives, wallet state, and P2P networking in one target. The winnow-debug tool and fuzz harness use that same implementation. Explorer links open an external website after a warning.

The testing and feature policy ties supported features to actual app journeys and names the lower-level invariants worth keeping. The homepage and Advanced page are generated from docs/journeys.json and the app test source; run scripts/build-site after changing either. CI rejects missing or undocumented app scenarios.

Directory guides

Each guide explains what its directory owns, why the app or debugging needs it, and which consumers and tests support that purpose. Every guide links back here. When adding an owned directory with code, data, or documentation, add its README and index link together. Parent folders with their own files need a guide too; asset catalogs are documented by their owner, outside the bundle.

App and Bitcoin rules

Tests and reference data

Debugging and fuzzing

Website and repository operations

Build & test

swift test
swift run winnow-debug inspect tx <hex>
xcodegen
scripts/ci-app-tests /tmp/winnow-app-tests
scripts/ci-debug

Use XcodeGen 2.46.0. scripts/install-xcodegen downloads and verifies that version; locally it prints the executable path to use. The generated Xcode project is ignored. Run app tests with a fresh results directory. Test fixtures live once, in the TestSupport library (Tests/Support); it imports neither Testing nor XCTest, so the swift-testing targets and the Xcode bundles share it and every assertion stays at the call site. scripts/check-dependencies --xcode /path/to/DerivedData verifies that Xcode uses the root package and its committed third-party dependency revision.

CI and release operations describes the shared validation gates, node fixture, TestFlight recovery and website deployment. The LOC workflow publishes JSON, CSV and Markdown reports for every PR, main push and manual run, retained for 90 days subject to organization limits. Its summary separates app/library/CLI source, tests, webpages, tooling and other text; generated peers, binaries and LFS pointers are excluded. See the counting policy.

Mainnet is the default network, and the app starts in beginner mode: one screen with the balance, Receive, Send, your activity, shared savings once you have any, and the backup — no settings. Open a payment to save or rename its recipient, then pick them from Saved recipients in Send. The same Send form handles every account: choose the account, recipient, and amount, then review the fee. Shared accounts continue to their required approvals before anything is sent. Advanced, in the corner of that screen, switches to the three-tab interface — Wallet, Send, Settings — with the test network, your own peers, chain verification, the block explorer, custom fees, fee bumping, build details and the raw vault tools; Simple, on the Wallet tab, switches back and keeps every setting. Switch to signet there for development. Point the app at your own filter-serving node (Settings → Manual peers); the node needs blockfilterindex=1 and peerblockfilters=1.

Screenshots

GUI diagnostics live in Tools/Debug. Use scripts/winnow-debug doctor for environment checks and scripts/winnow-debug diagnostics for local simulator logs and screenshots. The demo and publication workflow has been retired; functional GUI journeys remain in UITests.

Screenshot PNGs in docs/screenshots/ are stored in Git LFS. After cloning, install Git LFS and download the image objects before viewing or publishing them:

git lfs install --local
git lfs pull

The website workflow fetches LFS objects before publishing. The node workflow writes new screenshots into its run artifacts. Local test runs use fresh temporary directories. Select public images deliberately from a successful run; Git stores LFS pointers when those selected PNGs are added.

License

Winnow is available under the MIT License.

About

Bitcoin wallet for iPhone. Pay people, hold shared savings, and connect directly to Bitcoin peers.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages