Bonus guide: Samourai Dojo
Samourai Dojo is the backing server for Samourai Wallet. Provides HD account & loose addresses (BIP47) balances & transactions lists. Provides unspent output lists to the wallet. PushTX endpoint broadcasts transactions through the backing bitcoind node.
Difficulty: Medium
Status: Tested v3
Table of contents
- Requirements
- Preparations
- Installation
- Configuration
- Run Dojo
- Connect to Dojo
- For the future: Dojo upgrade
- Uninstall
Requirements
- Minimum RAM: 4 GB
- Bitcoin Core
- Fulcrum (recommended) / Electrs
- Node.js v16+
- Nginx
Preparations
Write down your passwords
Samourai Dojo requires you to generate several new passwords. They should be unique and very secure, at least 12 characters in length. Do not use uncommon special characters, spaces, or quotes (‘ or “). Store a copy of your passwords somewhere safe (preferably in an open-source password manager like KeePassXC) or whatever password manager you’re already using)
[ F ] MYSQL ROOT PASSWORD
[ G ] MYSQL PASSWORD
[ H ] NODE API KEY 1, NODE API KEY 2
[ I ] NODE ADMIN KEY
[ J ] NODE JWT SECRET
Node.js
To run Dojo, we need to run Node.js
-
With user “admin”, let’s check our version of Node.js running on the node. If the version is v14 or older, update it following this tutorial.
$ node -v > v16.13.1
-
If Node.js is not installed, add the Node.js package repository from user “admin” and install Node.js using the apt package manager
$ curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - $ sudo apt install nodejs
Node Package Manager & PM2
Node Package Manager (npm) is the default package manager for the JavaScript runtime environment and PM2 is a process manager for the JavaScript runtime Node.js
-
With user “admin”, let’s check our version of npm running on the node
$ npm -v > 8.19.2
-
If not already installed, install npm package manager
$ sudo apt update $ sudo apt install npm
-
Update npm to the latest version
$ sudo npm install latest-version
-
Install PM2 process manager
$ sudo npm i -g pm2
For Electrs
If you are using Electrs instead of Fulcrum, it is necessary to make following change inside Bitcoind configuration file. Fulcrum users can skip this step as it is already done.
-
Open
bitcoin.conf
$ sudo nano /home/bitcoin/.bitcoin/bitcoin.conf
-
Add following line preferably under “# Connections” or at the end of the file
zmqpubhashblock=tcp://0.0.0.0:8433 # For Dojo
-
Restart Bitcoind
$ sudo systemctl restart bitcoind
Installation
Download Samourai Dojo
-
As a user “admin” move to a temporary directory which is cleared on reboot
$ cd /tmp/
-
Get the latest download links at code.samourai.io/dojo. They change with each update
$ wget https://code.samourai.io/dojo/samourai-dojo/-/archive/v1.17.0/samourai-dojo-v1.17.0.tar.gz $ wget https://code.samourai.io/dojo/samourai-dojo/uploads/0c9f3d5d07396019f3bfb6449fe11e48/samourai-dojo-v1.17.0-fingerprints.txt $ wget https://code.samourai.io/dojo/samourai-dojo/uploads/4ad2b6e5c8a64f4a44bfd1ef12a5b1c8/samourai-dojo-v1.17.0-fingerprints.txt.sig
-
Calculate the checksum of the binary you’ve downloaded and compare it to the one provided in the fingerprints text file
$ sha256sum --ignore-missing --check samourai-dojo-v1.17.0-fingerprints.txt > samourai-dojo-v1.17.0.tar.gz: OK
-
Import the GPG public key of the developper that signed the fingerprints file
$ curl https://keys.openpgp.org/vks/v1/by-fingerprint/377DE507FDC47F020099E342CFA54E4C0CD58DF0 | gpg --import
-
Verify that the fingerprints file has actually been signed by that developper
$ gpg --verify samourai-dojo-v1.17.0-fingerprints.txt.sig > gpg: assuming signed data in 'samourai-dojo-v1.17.0-fingerprints.txt' > gpg: Signature made Fri Aug 5 13:59:09 2022 BST > gpg: using RSA key 377DE507FDC47F020099E342CFA54E4C0CD58DF0 > gpg: Good signature from "pavel.sevcik@protonmail.com <pavel.sevcik@protonmail.com>" [unknown] > [...]
-
If the signature checks out, unpack the binary
$ tar -xvf samourai-dojo-v1.17.0.tar.gz
MariaDB
MariaDB is an open source relational database. If MariaDB is already installed, skip the installation section.
-
With user “admin”, update the
apt
packages index and install MariaDB$ sudo apt install mariadb-server
-
Run the secure installation
$ sudo mysql_secure_installation
-
Enter the following answers in the shell and exit. Change “[ F ] MYSQL ROOT PASSWORD” to your password.
Enter current password for root (enter for none): [ F ] MYSQL ROOT PASSWORD Switch to unix_socket authentication [Y/n]: n Change the root password? [Y/n]: n Remove anonymous users? [Y/n]: Y Disallow root login remotely? [Y/n]: Y Remove test database and access to it? [Y/n]: Y Reload privilege tables now? [Y/n] Y
-
Now, open the MariaDB shell
$ sudo mysql > Welcome to the MariaDB monitor. Commands end with ; or \g. > [...] MariaDB [(none)]>
-
The instructions to enter in the MariaDB shell start after “MariaDB [(none)]>”. Enter each command one by one including “;”. You only change “[ G ] MYSQL_PASSWORD” to your corresponding password (must stay inside single quotes ‘password’)
MariaDB [(none)]> CREATE DATABASE dojo_db; > Query OK, 1 row affected (0.001 sec) MariaDB [(none)]> CREATE USER 'dojo'@'localhost' IDENTIFIED BY '[ G ] MYSQL PASSWORD'; > Query OK, 0 rows affected (0.005 sec) MariaDB [(none)]> GRANT ALL PRIVILEGES ON dojo_db.* TO 'dojo'@'localhost'; > Query OK, 0 rows affected (0.006 sec) MariaDB [(none)]> FLUSH PRIVILEGES; > Query OK, 0 rows affected (0.001 sec)
-
Exit MySQL shell
MariaDB [(none)]> exit
Create the dojo user and data directory
-
Create the user “dojo” and add him to the group “bitcoin” as well
$ sudo adduser --disabled-password --gecos "" dojo $ sudo adduser dojo bitcoin
-
Create the Dojo data directory and move Dojo
$ sudo mkdir -p /opt/dojo/ $ sudo mv /tmp/samourai-dojo-v1.17.0/* /opt/dojo/ $ sudo chown -R dojo:dojo /opt/dojo/
-
Create a symlink to /home/dojo/.dojo
$ sudo ln -s /opt/dojo /home/dojo/.dojo $ sudo chown -R dojo:dojo /home/dojo/.dojo
-
Switch to user “dojo”
$ sudo su - dojo
-
Display the link and check that it is not shown in red (this would indicate an error)
$ ls -la
Configuration
index.js
-
With user “dojo” move to “conf” directory. Rename
index-mainnet.js
toindex.js
$ cd /opt/dojo/static/admin/conf $ mv index-mainnet.js index.js
-
With user “dojo” move to “keys” directory. Rename index-example.js to index.js
$ cd /opt/dojo/keys $ mv index-example.js index.js
-
As user “dojo” open “index.js”
$ nano index.js
We will edit 6 parts of this file - bitcoind, database (db), ports, API auth, jwt and indexer. Change following values for each part of the file. Values have to be inside single quotes 'abc'
when shown, use your corresponding password instead of “[ X ] PASSWORD”
-
Find and edit these lines inside “bitcoind” part to following values
bitcoind: { [...] // Login user: 'raspibolt', // Password pass: '[ B ] Bitcoin RPC password', // ZMQ Tx notifications zmqTx: 'tcp://127.0.0.1:28333', // ZMQ Block notifications zmqBlk: 'tcp://127.0.0.1:8433',
-
Find and edit these lines inside “db” part to following values
db: { [...] // User user: 'dojo', // Password pass: '[ G ] MYSQL PASSWORD', // Db name database: 'dojo_db',
-
Find and edit these lines inside “ports” configuration to following values
ports: { // Port used by the API account: 9990, // Port used by pushtx API pushtx: 9991, // Port used by the tracker API trackerApi: 9992, [...]
-
Find and edit these lines inside “auth” configuration to following values
auth: { [...] // List of API keys (alphanumeric characters) apiKeys: ['[ H ] NODE API KEY 1', '[ H ] NODE API KEY 2'], // Admin key (alphanumeric characters) adminKey: '[ I ] NODE ADMIN KEY',
-
Find and edit these lines inside “jwt” configuration to following values
jwt: { [...] // Secret passphrase used by the server to sign the jwt // (alphanumeric characters) secret: '[ J ] NODE JWT SECRET',
-
Find and edit these lines inside “indexer” configuration to following values. Use port “50001” and “tcp” for Electrs
* Indexer or third party service [...] // Values: local_bitcoind | local_indexer | third_party_explorer active: 'local_indexer', // Port port: 50002, # Use 50001 for Electrs // Protocol for communication (TCP or TLS) protocol: 'tls' # Use tcp for Electrs
-
Save and exit
pm2.config
-
Still as user “dojo”, move to the dojo directory, rename pm2 config file and open it
$ cd /opt/dojo $ mv pm2.config.cjs.example pm2.config.cjs $ nano pm2.config.cjs
-
Change “INTERPRETER” value to “node” (at the beginning). Save and exit
[...] const INTERPRETER = 'node' // OR binary name like `node`
-
Exit “dojo” user session
$ exit
Dependencies
-
With user “admin”, install necessary dependencies while inside the Dojo folder.
$ cd /opt/dojo/ $ sudo npm install --omit=dev
-
Import Dojo scripts to the MariaDB database. Change [ F ] MYSQL_ROOT_PASSWORD to your password (must stay inside quotes: “password”)
$ sudo mysql -u"root" -p"[ F ] MYSQL_ROOT_PASSWORD" "dojo_db" < ./db-scripts/1_db.sql.tpl -v
-------------- > /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */ -------------- [...]
Tor Hidden Service
Tor is used to access “Dojo API and Maintanence tool” and to reach Dojo in an anonymous way.
-
Edit “torrc” file
$ sudo nano /etc/tor/torrc
-
Paste following values at the end of your
torrc
file# Dojo hidden service HiddenServiceDir /var/lib/tor/hsv3/ HiddenServiceVersion 3 HiddenServicePort 80 127.0.0.1:80
-
Restart Tor
$ sudo systemctl reload tor
-
Print hostname and write it down to a safe place
$ sudo cat /var/lib/tor/hsv3/hostname > xyz.onion
Nginx Reverse Proxy
Configure nginx.conf for Dojo Maintanence Tool.
-
Open “nginx.conf” file
$ sudo nano /etc/nginx/nginx.conf
-
Add following block at the end of your configuration file.
Note: If you’re running an app that also uses the nginx web server (e.g. Homer, Mempool etc), the http context is already present innginx.conf
. Simply edit it to match the options below.# RaspiBolt: Dojo configuration # /etc/nginx/nginx.conf # https://code.samourai.io/dojo/samourai-dojo/-/blob/develop/docker/my-dojo/nginx/nginx.conf http { include /etc/nginx/mime.types; default_type application/octet-stream; # Disable activity logging for privacy. access_log off; # Do not reveal the version of server server_tokens off; sendfile on; keepalive_timeout 95; # Enable response compression gzip on; # Compression level: 1-9 gzip_comp_level 1; # Disable gzip compression for older IE gzip_disable msie6; # Minimum length of response before gzip kicks in gzip_min_length 128; # Compress these MIME types in addition to text/html gzip_types application/json; # Help with proxying by adding the Vary: Accept-Encoding response gzip_vary on; include /etc/nginx/sites-enabled/*.conf; }
-
Create a new file called
dojo.conf
inside “sites-enabled” directory$ sudo nano /etc/nginx/sites-enabled/dojo.conf
-
Paste following values and change “xyz.onion” under “# Tor Site Configuration” to your newly generated hostname address
# RaspiBolt: Dojo configuration # /etc/nginx/sites-enabled/dojo.conf # https://code.samourai.io/dojo/samourai-dojo/-/blob/develop/docker/my-dojo/nginx/mainnet.conf # Proxy WebSockets # https://www.nginx.com/blog/websocket-nginx/ map $http_upgrade $connection_upgrade { default upgrade; '' close; } # WebSocket server listening here upstream websocket { server localhost:9990; } # Tor Site Configuration server { listen 80; server_name xyz.onion; server_tokens off; # Set proxy timeouts for the application proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; send_timeout 600; # Proxy WebSocket connections first location /v2/inv { proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } # PushTX server is separate, so proxy first location /v2/pushtx/ { proxy_pass http://localhost:9991/; } # Tracker server is separate, so proxy first location /v2/tracker/ { proxy_pass http://localhost:9992/; } # Proxy requests to maintenance tool location /admin/ { proxy_pass http://localhost:9990/static/admin/; } # Proxy all other v2 requests to the accounts server location /v2/ { proxy_pass http://localhost:9990/; } # Redirect onion address to maintenance tool location = / { return 301 /admin; } }
-
Test and restart nginx configuration
$ sudo nginx -t >nginx: the configuration file /etc/nginx/nginx.conf syntax is ok >nginx: configuration file /etc/nginx/nginx.conf test is successful $ sudo systemctl restart nginx
Run Dojo
-
Switch to user “dojo” and move to Dojo directory
$ sudo su - dojo $ cd /opt/dojo
-
Start Dojo
$ pm2 start pm2.config.cjs
┌─────┬─────────────────────────────────────────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬── ────────┬──────────┐ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │ ├─────┼─────────────────────────────────────────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼── ────────┼──────────┤ │ 4 │ Samourai Dojo - Accounts (mainnet) │ mainnet │ 1.17.0 │ fork │ 1137300 │ 45s │ 733… │ online │ 0% │ 98.6mb │ dojo │ disabled │ │ 5 │ Samourai Dojo - PushTX (mainnet) │ mainnet │ 1.17.0 │ fork │ 1137301 │ 45s │ 941… │ online │ 0% │ 72.0mb │ dojo │ disabled │ │ 6 │ Samourai Dojo - PushTX orhestrator (mainnet) │ mainnet │ 1.17.0 │ fork │ 1137328 │ 42s │ 103… │ online │ 0% │ 66.7mb │ dojo │ disabled │ │ 7 │ Samourai Dojo - Tracker (mainnet) │ mainnet │ 1.17.0 │ fork │ 1137337 │ 41s │ 766… │ online │ 0% │ 191.4mb │ dojo │ disabled │ └─────┴─────────────────────────────────────────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴── ────────┴──────────┘
-
Check the logs, you should expect following output (it will take a while for blocks to synchronise):
$ pm2 logs mainnet
3|Samourai | Ignoring invalid configuration option passed to Connection: acquireTimeout. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection 7|Samourai | 2022-09-26T16:26:08Z INFO Tracker : Added block header 409 (id=409) 7|Samourai | 2022-09-26T16:26:08Z INFO Tracker : Beginning to process new block header. 7|Samourai Dojo - Tracker (mainnet) | 2022-09-26T16:26:10Z INFO Tracker : Added block header 410 (id=410) 7|Samourai Dojo - Tracker (mainnet) | 2022-09-26T16:26:10Z INFO Tracker : Beginning to process new block header.
-
Once finished, following output is expected
7|Samourai Dojo - Tracker (mainnet) | 2022-09-26T19:13:15Z INFO Tracker : Processing active Mempool (7 transactions) 7|Samourai Dojo - Tracker (mainnet) | 2022-09-26T19:13:17Z INFO Tracker : Processing active Mempool (2 transactions) 7|Samourai Dojo - Tracker (mainnet) | 2022-09-26T19:13:19Z INFO Tracker : Processing active Mempool (8 transactions)
Autostart on boot
Now we’ll make sure Dojo starts as a service on the Raspberry Pi so it’s always running.
-
Still logged as a “dojo” user, save running processes with following command
$ pm2 save
-
Run these processes at reboot automatically. Copy entire generated output starting with “sudo”
$ pm2 startup
>[PM2] Init System found: systemd >[PM2] To setup the Startup Script, copy/paste the following command: >sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u dojo --hp /home/dojo
-
Exit “dojo” user session
$ exit
-
Paste your own output into the CLI as user “admin”, who has sudo privileges
$ sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u dojo --hp /home/dojo
>[ 'systemctl enable pm2-dojo' ] >[PM2] Writing init configuration in /etc/systemd/system/pm2-dojo.service >[PM2] Making script booting at startup... >[PM2] [-] Executing: systemctl enable pm2-dojo... >Created symlink /etc/systemd/system/multi-user.target.wants/pm2-dojo.service -> /etc/systemd/system/pm2-dojo.service. >[PM2] [v] Command successfully executed.
Connect to Dojo
Erase Samourai Wallet
To connect, you need to delete and restore already existing Samourai Wallet. Backend configuration can only be modified at the start of wallet creation/restore process. Following steps are recommended!
Check Mnemonic Phrase
- Navigate to the settings by tapping
⋮
on the top right of the Samourai toolbar and then tappingSettings
- Once in the settings screen tap on
Wallet
and thenShow Mnemonic
- Check if Mnemonic phrase is correct
Check Passphrase
- Move back to
Settings
and then tapTroubleshoot
- Tap
Passphrase test
to begin the test - You will be asked to enter your passphrase. Upon success you will be notified
Erase Wallet
- In
Settings
tapWallet
- At the bottom of this screen, tap
Secure erase wallet
Find Pairing Code
Connect samourai wallet to your own backend
-
Paste your hostname generated in Tor Hidden Service section into Tor browser with following syntax:
xyz.onion/admin
. You can bookmark this page for easier future access -
Authenticate with
[I] NODE ADMIN KEY
.
- You will find your QR code for samourai wallet under the
pairing section
.
Connect Samourai Wallet
- From the Samourai Wallet start screen, select mainnet and activate Tor
- Toggle the Dojo button on to connect to your own Dojo server
- Scan the pairing QR code displayed by your chosen Dojo implementation
- Tap Restore an existing wallet
Rescan public keys using Dojo Maintenance Tool (optional)
If no balance is shown in your samourai wallet, it is neccessary to rescan public keys as they are not tracked by Dojo yet.
- Log into
Dojo API and Maintenance Tool
using Tor browser - Move to
xpubs tool
, underTools
section - In samourai wallet go to
Settings > Wallet
, here you can find your public keys - Copy and paste all “zpubs” into
xpub tool
and rescan each public key separately
Samourai wallet uses zpubs by default, however if you use other address format than “bc”, it is neccessary to rescan other pubs as well
For the future: Dojo upgrade
-
Switch to “dojo” user
$ sudo su - dojo
-
Stop Dojo
$ pm2 stop mainnet
-
Following the installation section, download and install latest Dojo version, start Dojo
$ pm2 start mainnet
Uninstall
Uninstall Dojo
-
As user “admin”, stop and remove Dojo service
$ sudo systemctl stop pm2-dojo.service $ sudo systemctl disable pm2-dojo.service $ sudo rm /etc/systemd/system/pm2-dojo.service
-
Remove Dojo directory and Dojo user
$ sudo rm -R /opt/dojo $ sudo userdel -r dojo
Remove Tor Hidden Service
-
Remove Tor configuration. Comment or delete following lines
$ sudo nano /etc/tor/torrc
# Dojo hidden service #HiddenServiceDir /var/lib/tor/hsv3/ #HiddenServiceVersion 3 #HiddenServicePort 80 127.0.0.1:80
$ sudo systemctl restart tor
Remove Nginx configuration
-
Remove Nginx configuration for Dojo
$ sudo rm /etc/nginx/sites-enabled/dojo.conf $ sudo systemctl reload nginx
Remove MariaDB
-
Remove MariaDB
$ sudo service mysql stop $ sudo apt-get --purge remove "mysql*"
« Back: + Bitcoin