# joinstr

coinjoin implementation using nostr

Joinstr was launched as a proof of concept in August 2022. It uses nostr relays for coordination and has implementations in multiple languages.


# How does it work?

Joinstr protocol uses ALL| ANYONECANPAY SIGHASH flag and outputs are registered first. This reduces some steps in coordination required for coinjoin.

> Coinjoin with less steps using ALL|ANYONECANPAY
>
> <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-May/021696.html>

<img src="/files/HyTk9Fl0LwtNv6Ji2hGS" alt="" class="gitbook-drawing">

The process is simple and involves only 3 steps. All the users publish a new address in the first step for output registration. It is followed by publishing PSBT which has 1 input and all outputs signed with ALL | ANYONECANPAY. These PSBTs are combined, finalized and broadcasted.&#x20;

Users can decide the denomination, number of peers and nostr relays by creating pools.&#x20;

See NIP for details about pools used in joinstr: [https://gitlab.com/invincible-privacy/joinstr/-/blob/main/NIP.md](https://gitlab.com/invincible-privacy/joinstr/-/blob/main/NIP.md?ref_type=heads)

#### Costs

All users pay equal fees in every round which in total is used for transaction fees. Only 1 transaction is required for coinjoin and fees depends on the mempool when pool is created. Each user would pay approximately 2000 sats if 10 sat/vbyte fee rate is used for the coinjoin transaction. Participants can also use paid nostr relays although there needs to be at least 1 common relay between the participants for coordination to work properly.

Read more about [market making in joinstr](https://uncensoredtech.substack.com/p/market-makers-in-joinstr) to earn fees from pools.

#### Privacy

A new public/private key pair is used for creating pools and sending join request. Everything else is communicated using an encrypted channel in which all peers use the same key. All peers in a pool use the same IP address for a coinjoin round and its implemented using Riseup VPN. However, the protocol also supports Tor in which clients can refresh Tor circuits to avoid links between inputs and outputs.

Sybil Resistance: [AUT-CT](https://github.com/AdamISZ/aut-ct) is used to increase the cost of sybil attacks.&#x20;

#### Security

DoS vectors are reduced by using basic checks, ring signatures, encrypted nostr channels for each round and encouraging users to try paid, private, custom nostr relays.


# Comparison with other coinjoin implementations

{% hint style="info" %}
Nostr relays are used in joinstr and participants can use multiple relays in same round.
{% endhint %}

<table data-full-width="false"><thead><tr><th>Feature</th><th>joinstr</th><th>joinmarket</th><th>whirlpool</th><th>wabisabi</th></tr></thead><tbody><tr><td>Decentralized</td><td>✅</td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td>Programming Language</td><td>Python, Kotlin, Rust</td><td>Python, TypeScript</td><td>Java</td><td>C#</td></tr><tr><td>Fidelity Bonds</td><td>Not Required</td><td>Required</td><td>Not Required</td><td>Not Required</td></tr><tr><td>Coordination</td><td>nostr</td><td>IRC and Onion messages</td><td>Centralized</td><td>Centralized</td></tr><tr><td>Sighash</td><td>ALL | ACP</td><td>ALL</td><td>ALL</td><td>ALL</td></tr><tr><td>Equal amount outputs</td><td>Yes</td><td>No</td><td>Yes</td><td>No</td></tr><tr><td>Tor Dependency</td><td>No</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>Founder</td><td>/dev/fd0</td><td>belcher</td><td>TDevD</td><td>nopara73</td></tr></tbody></table>

#### Related Links

Joinmarket: <https://github.com/JoinMarket-Org/joinmarket-clientserver>\
Wabisabi: <https://github.com/zkSNACKs/WabiSabi>\
Whirlpool: <https://github.com/Samourai-Wallet/Whirlpool>


# Using joinstr

#### Android App

<figure><img src="/files/lYzTNvcm1VtOK2H6NXt9" alt=""><figcaption><p><br></p></figcaption></figure>

Download link: <https://gitlab.com/invincible-privacy/joinstr-kmp/-/releases>

* Run a bitcoin node with below config:\
  \
  `signet=1`\
  `prune=550`\
  \
  `[signet]`\
  `rpcport=38332`\
  `rpcuser=rpcuser`\
  `rpcpassword=password`\
  \
  `rpcbind=192.168.1.10`\
  `rpcallowip=192.168.1.1/24`\
  \
  Assuming 192.168.1.10 is the IP address of your device and 192.168.1.1 is the IP address of gateway. Device running bitcoin node and mobile should use the same wi-fi network.
* Create a bitcoin wallet and get some signet coins.
* Save nostr relay and RPC credentials in mobile app. Select wallet and VPN gateway.
* Create a pool and join it from another device. Enter denomination according to the available UTXOs. Select input which gets signed automatically and a coinjoin transaction will be broadcasted in a few seconds.

#### Electrum Plugin

* Download plugin from <https://gitlab.com/invincible-privacy/joinstr/-/tree/main/plugin/zip/>
* Extract in `electrum/electrum/plugins`
* Install [nostrj](https://pypi.org/project/nostrj/), pyqtspinner, pillow and qrcode sugin `pip`
* Save a nostr relay, denomination and peers in settings after enabling the plugin
* Restart electrum and start using coinjoin

Tutorial: <https://uncensoredtech.substack.com/p/tutorial-electrum-plugin-for-joinstr>

<figure><img src="/files/dY4cqhEeh2L1u3UA8nVp" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/w8JMNY79XFsEuHio6k3s" alt=""><figcaption></figcaption></figure>


# FAQs

Frequently Asked Questions

1. Can I use joinstr on mainnet right now?\
   \
   Yes.<br>
2. Can I use joinstr without bitcoin core?\
   \
   Yes. It can be used as an electrum plugin which does not require bitcoin core. Although it is advised to use your EPS for better privacy instead of default electrum servers.<br>
3. Can I use joinstr on mobile?\
   \
   Yes. Android and iOS.<br>
4. What fees do I need to pay for using joinstr?\
   \
   a) Transaction fees which is contributed by all the participants\
   b) Nostr relay fee if using a paid relay\
   \
   Read more about [market making on joinstr](https://uncensoredtech.substack.com/p/market-makers-in-joinstr) to earn fees from pools.<br>
5. What pool denominations are supported in joinstr coinjoin rounds?\
   \
   Users can configure it and create pools based on custom denominations.&#x20;


# Designers

Figma link: <https://www.figma.com/file/UtMGwoJPpL8FNUmsdqYoeQ/joinstr-%F0%9F%A6%83-Design>


# Developers

Gitlab group: [https://gitlab.com/invincible-privacy/](https://gitlab.com/invincible-privacy/joinstr/)


# Privacy Researchers

<figure><img src="/files/eGcWk5bIC73VIIy87srb" alt=""><figcaption></figcaption></figure>


