Skip to content

Tor in the App

The node a phone sends a payment to would otherwise see the phone’s IP address next to it, and could tie a wallet’s deposits, payments and withdrawals together by address. So since 2026-11-07 the app carries Tor itself.

The app embeds Arti, Tor’s Rust implementation, inside wallet-core. With “Connect through Tor” on, which is the default:

  • every request to a Cheshire node goes through Tor;
  • each contribution goes on a fresh circuit of its own, to a node picked at random, so a node cannot group a wallet’s sends by circuit;
  • Bitcoin peers, the DNS seeds that find them, and the wallet’s own Bitcoin transactions go through Tor too;
  • a node can be reached at its .onion address, with no exit relay in between;
  • nothing is sent while Tor starts, and nothing ever falls back to a direct connection.
observer learns does not learn
the node that receives a contribution the contribution, and when your IP address; which other contributions are yours
your Wi-Fi or carrier that you use Tor, when and how much that you use Cheshire, or which node
your Tor guard relay your IP address, when and how much where the traffic goes
a Tor exit (clearnet nodes and peers only) which node or peer, when, the size your IP address
Bitcoin peers an exit’s address, the blocks and filters asked for your IP address

Tor does not hide timing from someone who can watch both your side and the node’s side, the amounts and timing at the pool’s boundary, or anything public on the share chain. With Tor switched off, the node you send to sees your IP address again.

Measured from a Mac on the live Tor network: start-up about 4 s; a request through an exit about 1 s once a circuit exists; a fresh circuit to an onion node about 5 s, which is what each contribution pays. Tor adds about 10 MB to the app.

Why not Dandelion++ or a relay? A phone’s first hop is always a node, which knows the phone sent the payment, so a Dandelion++ stem in the node never protected a phone; it was removed. Oblivious HTTP needs a relay run by someone independent of the node, and none exists.

Run end to end in the iOS simulator against stand-in nodes as onion services (a sync, Bitcoin peers, a deposit and a payment through Tor; no request arrived directly). Mainnet Bitcoin peers were reached through Tor from a Mac. Unaudited.