Requirements:
- python-nostr
- Bitcoin Core
Usage:
CLI
- Run
python joinstr-cli.py
and enter descriptor for one of the inputs. - Script will check inputs for this round in every 30 seconds and register a new adddress for output once 5 inputs are registered.
- Similar check happens every 30 seconds for outputs. Last peer should create a PSBT.
- Unsigned PSBT will be printed and signed by wallet with
walletprocesspsbt
RPC. - Script will check signed PSBTs and last peer should finalize coinjoin transaction once 5 signed PSBTs are received.
- Coinjoin transaction will be broadcasted and txid will be printed.
GUI
- Clone repo so that templates are available for using
joinstr-web
- Run
export FLASK_APP=joinstr-web
,flask run
and open http://127.0.0.1:5000/ in browser. - Select one of the inputs from wallet and submit for input registration.
- A new address will be registered for output once 5 inputs are registered for this round.
- PSBT will be created and shared.
GUI is a work in progress and other phases (signing PSBT and broadcasting) are left.
Examples:
CLI
List of utxos in wallet:
wpkh([53830dca/84'/1'/0'/0/0]02449be5fb74725255eeeb50eba930fa87705f21e99d13cd710cf2c1f21153c808)#x2hyyeg5
Enter descriptor for the input registration: wpkh([53830dca/84'/1'/0'/0/0]02449be5fb74725255eeeb50eba930fa87705f21e99d13cd710cf2c1f21153c808)#x2hyyeg5
event id: bcbbe62d75d99fed73f1e50ac58a38d1840b658951893e63c032
6704
2b378d7d56f0
tb1qhxrp4zl54ul0twtyz0gury5399q7z0kvqqrl6m registered for output
event id: 9449c9065bef356d21507a98f88b028b17fc1c49eb195c8d4420604fcaaef041
Unsigned PSBT: cHNidP8BAP1yAQIAAAAFtMaoJYcXvOG5L3Yaz3YyS7gIt4h5/zzOrRRS3hrVvwoAAAAAAP////+o83geaSm4L76KToIUl5MiZqLAUbIDJLq6DWrjP/3b8AEAAAAA/////zEF3CXIvVHpIa7No1s1yg+KtyOfXTRSyWnOdXMfzcDwAQAAAAD/////wMa4XAgnU+39Ien+KG9rYtv8bLMNYakmZyY/QFfwLRcAAAAAAP/////5M42ID6uLmQTb2tnFHnN7UMpnDD25uN8ZX7A+GNSM3QEAAAAA/////wV4xwEAAAAAABYAFLmGGov0rz71uWQT0cGSkSlB4T7MeMcBAAAAAAAWABSc0/FM6Hdbdxh10IJkYOklVFWqjnjHAQAAAAAAFgAUPSZKe/w6PT6qIF+WhL4wHaFymjd4xwEAAAAAABYAFMx0rxYlpPWB3NFry4Ctk2eVi/UNeMcBAAAAAAAWABSzc4xK0VTfvjK0MHXrAUFLYgYnOgAAAAAAAAAAAAAAAAAAAA==
Signed PSBT: cHNidP8BAP1yAQIAAAAFtMaoJYcXvOG5L3Yaz3YyS7gIt4h5/zzOrRRS3hrVvwoAAAAAAP////+o83geaSm4L76KToIUl5MiZqLAUbIDJLq6DWrjP/3b8AEAAAAA/////zEF3CXIvVHpIa7No1s1yg+KtyOfXTRSyWnOdXMfzcDwAQAAAAD/////wMa4XAgnU+39Ien+KG9rYtv8bLMNYakmZyY/QFfwLRcAAAAAAP/////5M42ID6uLmQTb2tnFHnN7UMpnDD25uN8ZX7A+GNSM3QEAAAAA/////wV4xwEAAAAAABYAFLmGGov0rz71uWQT0cGSkSlB4T7MeMcBAAAAAAAWABSc0/FM6Hdbdxh10IJkYOklVFWqjnjHAQAAAAAAFgAUPSZKe/w6PT6qIF+WhL4wHaFymjd4xwEAAAAAABYAFMx0rxYlpPWB3NFry4Ctk2eVi/UNeMcBAAAAAAAWABSzc4xK0VTfvjK0MHXrAUFLYgYnOgAAAAAAAQBxAgAAAAG+qpMXZCy6tBuUlgo8JD0GVXKp60FkhwDeg2sF1fkFkwMAAAAA/f///wLo9wEAAAAAABYAFFfLA5xarC/w/SxeMDQ5tuXrYJLUWwMAAAAAAAAWABRfPf//hwMjHB4OKj87cU19XOSh7yOWAQABAR/o9wEAAAAAABYAFFfLA5xarC/w/SxeMDQ5tuXrYJLUAQhrAkcwRAIgOIhLoC5348U8YkEr4GU1K4yWskIOEXgW4Wsk/W2cR7ICIEJXqtOuDJ5CkwrSuwJLWtzab4dslbN3KuL/pyooMnOCASECRJvl+3RyUlXu61DrqTD6h3BfIemdE81xDPLB8hFTyAgAAAAAACICA77Cnd6o3kr0yc+91eabpOn5igs/MUMbudNYSS6oyMWMGFODDcpUAACAAQAAgAAAAIAAAAAAFAAAAAAAAAAA
event id: 5846b6e6902f3c5a43496d7d9785ed62444aa74963f03c33d637d8b09ee7a139
Coinjoin tx: 75e490b10b15a6a0422f25ff66ad98ef70390c8fecaac02712705dce8cc3564b
event id: 9b5d4bf279b59e2b6e539e683fba83da72dce2b640360aa95db1b1400be93190
GUI
TO DO:
- Send each request using new tor circuit.
- Use NIP 38/48 (encrypted channels) to improve privacy and security.
- Break UTXOs in pool denominations before coinjoin.
- Do not allow registering different types of inputs for a round.
- Use NIP 9 to delete events after round is completed
- Create an Android app.
🟢 Matrix room: #joinstr:matrix.org
🟢 Nostr channel: 379bfcf8b739b4ca3c117c729c3c9311dd7868a04433d4aa413989ee2945ba81
Do not use this script for mainnet as there are several bugs in the code and lot of scope for improvement.