SwitchBitcoin

Trustless Bitcoin UTXO ownership transfer. Two wallets swap equal-amount coins through adaptor-signature atomic settlement — no operator, no coordinator, no custody, ever.

A desktop, peer-to-peer protocol wallet. This site is an information and distribution channel only: downloads, checksums, signed parameter manifests, and the tester guide. Nothing key-touching runs here, and there is no web wallet.

What it is

SwitchBitcoin settles a two-party coin swap with a novel composition of well-understood primitives: MuSig2 (BIP 327) Taproot escrows, adaptor-signature atomic settlement, ordered refund timelocks, and baked-in fees — composed so that a funded swap always has exactly two exits: it completes, or it refunds. There is no third state, and no party who can hold your coins.

Protocol lineage: v3.16 specification, unchanged (formerly developed under the internal codename "Swap Key"; current spec document: v18). Pinned, audited cryptography only — MuSig2, adaptor signatures, and nonces come from libsecp256k1 bindings; nothing curve-related is hand-rolled.

How strangers meet

A swap needs two people. If you already know your counterparty, you hand them a ticket and you're done. If you don't, you have to find one — without a company in the middle doing the matching. Here is how that works, in plain terms.

The ticket is a phone number

One line of text, skt1…. It says where to call and proves you reached the right person. Give it to a partner however you like — it is the whole handshake.

Nostr relays are public noticeboards

To be found by a stranger, your wallet pins a sealed note to several public boards: "someone would like to swap this size." No name on it, a fresh single-use key signs each one, and it is posted through Tor.

Tor is the unlisted call

When someone answers your note, the two wallets meet on a one-shot onion address created for that rendezvous and nothing else. Neither side learns the other's IP, and the boards never learn the address.

The part worth being precise about: the relays only ever carry the "want to meet?" notes. Everything after that — the negotiation, the escrows, the settlement — runs directly between the two wallets over Tor, through the same code the hand-delivered path uses. No transaction id, no escrow, no ticket, and no onion address is ever published to a relay; that one is enforced by a test that inspects every relay-bound byte of a complete swap.

What we will not claim

The hand-delivered path is the private one, and it is permanent

If you already have a partner, trading a ticket directly publishes nothing, anywhere — no note on any board, no proof-of-work, no public infrastructure touched at all. That remains the lowest-metadata way to use SwitchBitcoin, it is supported forever, and discovery is an addition to it, never a replacement. swap --make-onion gives you the Tor rendezvous with a hand-delivered ticket: no relays, no IP.

Honest status — read before touching anything

Testnet only

Mainnet is structurally impossible in this build — no configuration reaches it. That stays true until the external cryptographer review clears. Treat every coin this software touches as expendable test money.

~Half of swaps refund, by design

A safety pre-commitment fix is deliberately deferred to the cryptographer review. Until it clears, convention-mismatched attempts refuse and close through the refund path — funds come back automatically at the timelock. A refunded swap is the safety system working.

The hard gate is open

This is a novel composition, and novel compositions are where sound primitives are most often assembled unsoundly. The scoped external cryptographer review is the gate to everything beyond testnet — it is not substitutable by internal analysis, and its packet is ready and waiting.

Named debts, not waived

Tor transport and discovery have since been built and run live (2026-07-27). Still open and still named: corpus fuzzing under sanitizers (host limitation; a seven-surface hostile-input sweep ran interim), third-party watchtower delegation, enclave custody, and the public relay population that keeps discovery from starting unaided. None quietly dropped.

Proven live on testnet4

The settlement core is implemented in full as a Rust crate — 594 automated tests green in the default configuration, 643 with the Bitcoin Core backend, lint-clean in both — and the claims below are backed by on-chain evidence recorded in the repository's artifact log:

2026-07-16 — first live swap. Exact-D outputs on both sides, 124 vB Setup and Completion transactions, baked fees consumed exactly as signed. No coordinator, no external input.
2026-07-17/18 — dead-device refund drill. Wallet process killed after both escrows funded; the watchtower re-armed from a restored backup and survived a real machine reboot mid-timelock. The pre-armed refund fired on the tower's first poll after re-arm: 143 vB exact, confirmed on chain, wallet reconciled to Refunded.
2026-07-18 — signed-manifest governance round. The fleet converged on manifest v2; a staggered-rollout drill refused before dialing as designed; a four-arm operator-error matrix (retired key, corrupted payload, corrupted signature, version swap) refused cleanly on every arm. The round included a real operator key rotation after a passphrase loss — the documented recovery procedure, exercised for real, with anti-rollback held throughout.
2026-07-27 — two strangers met with zero out-of-band bytes. Two wallets, separate data directories and separate Tor runtimes, found each other on public Nostr relays over Tor. The taker learned the offer from its own scan — nothing was pasted between them — took it, received an encrypted reply, decoded a byte-identical rendezvous ticket, dialled the ephemeral onion it named, and negotiated a swap session with the settlement core: same session id, same funding order, same coordination height on both sides. The maker's escrow funded and confirmed on testnet4. What is not yet proven: the swap did not complete — the session ended before the taker funded — and no discovered swap has been observed settling end to end. The same run caught three real bugs no test could see, including ephemeral onion services being destroyed at the instant they were created, which means no onion rendezvous had ever actually worked before that day.
2026-07-29 — the refund fired, on its own, with the wallet dead. That unfinished swap was left with a funded escrow and a counterparty who had vanished, which is the case the whole design exists to survive. We took a backup of the dead wallet, restored it onto a second data directory, and pointed a watchtower at it. The watchtower broadcast the refund that had been signed and set aside back when the swap was negotiated, before any coin was at risk; it confirmed on testnet4 in block 146216 and the tower stood itself down. The money came back without the original wallet ever running again. This is a refund, not a completion — it proves the forward-or-refund promise, not end-to-end settlement between strangers. Running the remaining failure drills also caught two more real defects: a maker whose offer was taken by someone who never showed up used to abandon its whole session, and a message that told makers "the taker will not see it" when the taker demonstrably did. Both fixed in the "-e" build.

MuSig2 / BIP 327 Tor rendezvous Nostr discovery (testnet) Taproot escrows Adaptor signatures TRUC / v3 + P2A anchors CPFP congestion backstop Signed-manifest governance

Downloads

Pre-alpha tester package — 0.1.0 (git 6e5585ee0, patch "-e"), Windows x86_64: switchbitcoin-prealpha-0.1.0-6e5585ee0-windows-gnu.zip (~8.6 MB) · release page. New in "-e": a maker that had an offer taken by someone who never showed up used to give up entirely — one no-show ended the whole session, and the anti-griefing cooldown that was supposed to handle it could never run. A maker now charges the cooldown and keeps serving. Also corrected: when a maker cannot publish its rendezvous answer to enough relays it said "the taker will not see it", which we caught being false in a live drill — the taker often does see it, and then dials an address the maker has already torn down. Nothing is ever leased or owed in that case, on either side, and the message now says what actually happens. Carried over from "-d": discovery — your wallet can find a counterparty on public Nostr relays over Tor (testnet, and read guide §6 first: it needs a Tor binary you fetch and verify yourself, and it deliberately refuses to start until you add a third relay). Also: ephemeral onion services were being destroyed at the instant they were created, so no onion rendezvous could ever have worked on an earlier build — if one timed out on you, that was us, not your network. Two further fixes from the same live run: the discovery scan loop no longer hammers relays ~60× harder than its own flag claimed, and the rendezvous dial ladder is now sized for real onion descriptor propagation. It ships the two binaries (switchbitcoin-cli, switchbitcoin-manifest), the tester guide, the bug-report template, the current signed manifest, the local HTML wallet UI, and SHA256SUMS — built by a release script that refuses to package any binary failing the full test gates or carrying a test trust root (this cut: 594 green default, 643 with the Bitcoin Core backend, lint-clean in both).

Source code: github.com/abysal32-arch/switchbitcoin (MIT). switchbitcoin-cli version embeds the git commit the binary was built from — current release 6e5585ee0, tag v0.1.0-prealpha-e — so the hash chain can be checked against the repository and the release page, not just this site.

Zip SHA256 (verify before extracting):

8729ff80302fc8ddb9a9a4fdfe1cd1e159b583b8df2d18a5ac5486b8e9ecdde9

Pre-alpha testers are hand-picked. Verify the zip hash and the per-file SHA256SUMS before running anything, and check switchbitcoin-cli version prints the pinned trust root below.

Trust root (operator public key)

Every wallet build pins this BIP340 x-only public key at compile time. Signed parameter manifests that do not verify against it are refused. Cross-check the key your binary prints (switchbitcoin-cli version) against this page:

fedd62229b6c8a194d6d174d68ad0ce303623cbd49df4b968b9b06ea9e6ec7fe

This is the SECOND operator key (generated 2026-07-16). The first (fbb01df4…a2191e) was retired via the documented key-loss rotation; manifests it signed no longer verify — by design.

Signed parameter manifests

Settlement parameters are distributed as signed constants — never wallet settings. Each manifest is a 169-byte BIP340-signed envelope with a strictly-increasing version; wallets refuse replays, downgrades, and anything the pinned key didn't sign. Everyone in a test round runs the same version; ingest with switchbitcoin-cli manifest ingest <file>.

VersionFilesStatus
v3 (current) v3.manifest · v3-params.toml (readable source) Signed 2026-07-20 by the current operator key. Id e962918a44f7dd644985725e035675ba7f6d2db1e42c0e7066d5b3449ece0400. Sole change vs v2: swap tier 0.01 → 0.001 tBTC (test tier for the live testnet4 round — units fundable from ordinary faucet drips; the production 0.01 tier returns as a future v4).
v2 (history) v2.manifest · v2-params.toml Signed 2026-07-16 by the current operator key. Id cdda51a9…b011300e. Sole change vs v1: onboarding delay 1–2 h (testing period; the production-scale 24–72 h returns in the first post-testing round). Tier superseded by v3 for the testing round.
v1 (history) v1.manifest · v1-params.toml Signed by the RETIRED first key — no longer verifies, kept as the governance-history record of the 2026-07-16 rotation.

Even a compromised operator key cannot push parameters that violate the wallet-side ordering invariant — bounds are asserted signature-blind on every compose, ingest, and load.

Testing & bug reports

Start with the Tester Guide — it takes you from nothing to a completed swap (own Bitcoin Core node required; there is deliberately no hosted RPC option) and keys every troubleshooting entry to the exact strings the wallet prints.

Bugs: run switchbitcoin-cli diag (redacted by construction — no seed, mnemonic, passphrase, or RPC secrets), fill in the bug-report template shipped in the package, and send it through the channel you were onboarded with. Pre-alpha testers are hand-picked; there is no public tracker yet.