# Clients

joinstr has several independent clients. Pick the one that matches the wallet you already use.

| Client | Platform | Wallet backend | Transports | aut-ct | Source |
|---|---|---|---|---|---|
| [Electrum plugin](electrum.md) | Linux, macOS, Windows | Electrum server | Tor, VPN | Yes | [invincible-privacy/joinstr](https://gitlab.com/invincible-privacy/joinstr/-/tree/main/plugin) |
| [Web UI](web-ui.md) | Browser, Umbrel | Bitcoin Core | Tor | No | [invincible-privacy/joinstr](https://gitlab.com/invincible-privacy/joinstr/-/tree/main/gui) |
| [Daemon and CLI](daemon-cli.md) | Python 3 | Bitcoin Core | Tor | No | [invincible-privacy/joinstr](https://gitlab.com/invincible-privacy/joinstr/-/tree/main/cli) |
| [Android app](android.md) | Android 7.0 or newer | Bitcoin Core | Tor, VPN | No | [invincible-privacy/joinstr-kmp](https://gitlab.com/invincible-privacy/joinstr-kmp) |
| [Sparrow](sparrow.md) | Linux, Windows | Any Sparrow server | Tor | Yes | [QcMrHyde/sparrow-joinstr](https://github.com/QcMrHyde/sparrow-joinstr) |
| [Rust and Dart library](rust.md) | Library | Electrum server | Optional SOCKS5 | No | [rust-joinstr/joinstr](https://github.com/rust-joinstr/joinstr) |

The Electrum plugin is the reference implementation. The [protocol page](../protocol/index.md) describes what it sends and checks.

## Release signing

Releases of the Electrum plugin and the Android app are signed with the PGP key of /dev/fd0.

```
9253 062A 4F92 D634 5908  5CA6 2D23 0520 212A 5901
```

Fetch it from keys.openpgp.org.

```sh
gpg --keyserver hkps://keys.openpgp.org --recv-keys 9253062A4F92D63459085CA62D230520212A5901
```

Each client page shows how to verify its download.
