Add Samourai Wallet's Whirlpool (#76)

* basic files and pages

* Create whirlpool.service

* Added Whirlpool port

* add openjdk-8-jre

* Whirlpool dependencies

* updates for PR

added line 26 and 27
removed second argument from wget

* Whirlpool edit

added sudo -u bitcoin

* instructions for setting up whirlpool

* corrected line 25

sudo -u bitcoin mkdir -p

* minor changes in instructions

* Create setup_whirlpool.sh

* updated instructions and deleted repeated code

* Delete setup_whirlpool.sh

* Set for future upgrades

* renamed whirlpool.jar

based on post_install.sh

* systemctl enable whirlpool

* use black/white whirlpool logo

* Update mynode_post_upgrade.sh

* Update mynode_post_upgrade.sh

* Update bitcoin.conf

updated for dojo

* Update mynode_post_upgrade.sh

* Update mynode_post_upgrade.sh

* Update mynode_post_upgrade.sh

* Update mynode_post_upgrade.sh

* Update mynode_post_upgrade.sh

* dojo compatible conf

updated for dojo

* update Whirlpool-cli to 0.9.2

* Update to whirlpool 0.9.3

Co-authored-by: Abhishek Shandilya <abhiShandy@users.noreply.github.com>
Co-authored-by: Taylor Helsper <tehelsper@gmail.com>
This commit is contained in:
BTCxZelko 2019-12-25 20:38:30 -08:00 committed by Taylor Helsper
parent 4cb1f74d85
commit 0ce9cea96c
14 changed files with 233 additions and 5 deletions

View File

@ -44,4 +44,4 @@ bind=127.0.0.1
# Tor only (default)
onlynet=onion
dnsseed=0
dns=0
dns=0

View File

@ -0,0 +1,17 @@
[Unit]
Description=Whirlpool
After=tor.service
[Service]
WorkingDirectory=/opt/mynode/whirlpool
ExecStart=/usr/bin/java -jar /opt/mynode/whirlpool/whirlpool.jar --server=mainnet --tor --auto-mix --mixs-target=3 --listen
User=bitcoin
Group=bitcoin
Type=simple
KillMode=process
TimeoutSec=60
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target

View File

@ -35,7 +35,7 @@ ufw allow 51194 comment 'allow VPN'
ufw allow 61208 comment 'allow glances'
ufw allow from 127.0.0.1 comment 'allow from localhost'
ufw allow from ::1 comment 'allow from localhost'
ufw allow 8899 comment 'allow Whirlpool'
# Enable UFW
ufw --force enable
@ -51,4 +51,4 @@ ufw reload
ufw logging off
# Success
exit 0
exit 0

View File

@ -33,6 +33,30 @@ apt-get -y purge ntp # (conflicts with systemd-timedatectl)
apt-get -y purge chrony # (conflicts with systemd-timedatectl)
# Install Whirlpool
apt -y install openjdk-8-jre
WHIRLPOOL_UPGRADE_URL=https://github.com/Samourai-Wallet/whirlpool-client-cli/releases/download/0.9.3/whirlpool-client-cli-0.9.3-run.jar
WHIRLPOOL_UPGRADE_URL_FILE=/home/bitcoin/.mynode/.whirlpool_url
CURRENT=""
if [ -f $WHIRLPOOL_UPGRADE_URL_FILE ]; then
CURRENT=$(cat $WHIRLPOOL_UPGRADE_URL_FILE)
fi
if [ "$CURRENT" != "$WHIRLPOOL_UPGRADE_URL" ]; then
if [ ! -d /opt/mynode/whirlpool ]; then
sudo -u bitcoin mkdir -p /opt/mynode/whirlpool
cd /opt/mynode/whirlpool
else
cd /opt/mynode/whirlpool
sudo rm -rf *.jar
fi
sudo -u bitcoin wget -O whirlpool.jar $WHIRLPOOL_UPGRADE_URL
mkdir -p /home/bitcoin/.mynode/
chown -R bitcoin:bitcoin /home/bitcoin/.mynode/
echo $WHIRLPOOL_UPGRADE_URL > $WHIRLPOOL_UPGRADE_URL_FILE
fi
# Install any pip software
pip install tzupdate virtualenv --no-cache-dir
@ -67,7 +91,6 @@ usermod -aG docker admin
usermod -aG docker bitcoin
usermod -aG docker root
# Upgrade BTC
echo "Upgrading BTC..."
BTC_VERSION="0.19.0.1"
@ -300,6 +323,7 @@ systemctl enable docker_images
systemctl enable glances
systemctl enable netdata
systemctl enable webssh2
systemctl enable whirlpool
# Disable any old services
systemctl disable hitch

View File

@ -108,4 +108,15 @@ def enable_netdata():
def disable_netdata():
os.system("systemctl stop netdata --no-pager")
os.system("systemctl disable netdata --no-pager")
os.system("systemctl disable netdata --no-pager")
def is_whirlpool_enabled():
return is_service_enabled("whirlpool")
def enable_whirlpool():
os.system("systemctl enable whirlpool --no-pager")
os.system("systemctl start whirlpool --no-pager")
def disable_whirlpool():
os.system("systemctl stop whirlpool --no-pager")
os.system("systemctl disable whirlpool --no-pager")

View File

@ -4,6 +4,7 @@ from flask import Flask, render_template, Markup, send_from_directory, redirect,
from user_management import *
from bitcoind import mynode_bitcoind
from bitcoin_cli import mynode_bitcoin_cli
from whirlpool import mynode_whirlpool, get_whirlpool_status
from tor import mynode_tor
from vpn import mynode_vpn
from electrum_server import *
@ -41,6 +42,7 @@ app.config['UPLOAD_FOLDER'] = "/tmp/flask_uploads"
app.register_blueprint(mynode_bitcoind)
app.register_blueprint(mynode_lnd)
app.register_blueprint(mynode_bitcoin_cli)
app.register_blueprint(mynode_whirlpool)
app.register_blueprint(mynode_tor)
app.register_blueprint(mynode_electrum_server)
app.register_blueprint(mynode_vpn)
@ -372,6 +374,9 @@ def index():
else:
vpn_status = "Setting up..."
# Find whirlpool status
whirlpool_status, whirlpool_status_color, whirlpool_initialized = get_whirlpool_status()
# Check for new version of software
upgrade_available = False
current = get_current_version()
@ -408,6 +413,10 @@ def index():
"vpn_status_color": vpn_status_color,
"vpn_status": vpn_status,
"vpn_enabled": is_vpn_enabled(),
"whirlpool_status": whirlpool_status,
"whirlpool_status_color": whirlpool_status_color,
"whirlpool_enabled": is_whirlpool_enabled(),
"whirlpool_initialized": whirlpool_initialized,
"product_key_skipped": pk_skipped,
"product_key_error": pk_error,
"fsck_error": has_fsck_error(),
@ -514,6 +523,15 @@ def page_toggle_vpn():
enable_vpn()
return redirect("/")
@app.route("/toggle-whirlpool")
def page_toggle_whirlpool():
check_logged_in()
if is_whirlpool_enabled():
disable_whirlpool()
else:
enable_whirlpool()
return redirect("/")
@app.route("/login", methods=["GET","POST"])
def page_login():
templateData = {"ui_settings": read_ui_settings()}

View File

@ -231,6 +231,34 @@ a:active {
margin-bottom: 40px;
}
.instructions {
width: 75%;
color: #444444;
margin: auto;
text-align: left;
font-size: 18px;
font-family: Arial, Helvetica, sans-serif;
margin-bottom: 40px;
margin-top: 40px;
}
.instructions-header {
font-size: 18px;
text-align: center;
}
.instructions-steps li {
padding: 0.25em;
}
.instructions-terminal {
font-family: "Courier New", Courier, monospace;
}
.instructions-keyboard {
font-weight: bold;
}
.mynode_button {
width: 80%;
font-size: 14px;

View File

@ -25,6 +25,7 @@ a:active {
.app_contents,
.info_tile_contents,
.content_block,
.instructions,
.drive_usage,
.settings_block_header,
.settings_block_subheader,

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -106,4 +106,22 @@
<div class="app_status"></div>
<div class="app_contents"><a class="ui-button ui-widget ui-corner-all mynode_button" href="/bitcoin-cli">CLI</a></div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ whirlpool_status_color }}"></div>
{% if ui_settings['darkmode'] %}
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/wp-white.png")}}"/></div>
{% else %}
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/wp-black.png")}}"/></div>
{% endif %}
<div class="app_title">Whirlpool</div>
<div class="app_status">{{ whirlpool_status }}</div>
<div class="app_contents">
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/whirlpool">
{% if whirlpool_initialized %}Info{% else %}Setup{% endif %}
</a>
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/toggle-whirlpool">
{% if whirlpool_enabled %}Disable{% else %}Enable{% endif %}
</a>
</div>
</div>
</div>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html lang="en">
<head>
<title>{{ title }}</title>
{% include 'includes/head.html' %}
</head>
<body>
{% include 'includes/logo_header.html' %}
<div class="mynode_back_div">
<a class="ui-button ui-widget ui-corner-all mynode_back" href="/"><span class="ui-icon ui-icon-home"></span>home&nbsp;</a>
</div>
<div class="main_header">Samourai Whirlpool</div>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">Status</div>
<div class="info_tile_contents">{{whirlpool_status}}</div>
</div>
{% if whirlpool_enabled and whirlpool_initialized %}
<div class="info_tile">
<div class="info_tile_header">API Key for Whirlpool GUI</div>
<div class="info_tile_contents">{{whirlpool_api_key}}</div>
</div>
{% endif %}
{% if whirlpool_enabled %}
<div class="info_tile">
<div class="info_tile_header">Restart</div>
<div class="info_tile_contents">
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 70%;" href="/restart-whirlpool">Restart</a>
</div>
</div>
{% endif %}
</div>
<div class="instructions">
<div class="instructions-header">Instructions to setup Whirlpool</div>
<ol class="instructions-steps">
<li>You will need the Samourai wallet passphrase and pairing payload in next steps.</li>
<li>To get the pairing payload, open up your Samourai mobile wallet. Press 3 dots on top right -> Settings -> Transactions-> Pair to Whirlpool GUI. Copy the code to clipboard and send the code to yourself securely. It would look something like:<br>{"pairing":{"type":"whirlpool.gui","version":"3.0.0"...</li>
<li>Download and install Whirlpool GUI from <a href="https://github.com/Samourai-Wallet/whirlpool-gui/releases" target="_blank">https://github.com/Samourai-Wallet/whirlpool-gui/releases</a>.</li>
<li>Ensure that Whirlpool is running on myNode and status is "Waiting for initialization".</li>
<li>Select "Connect to remote CLI". Type in http://mynode.local (or the IP address of your myNode in the http://&lt;mynode-IP-address&gt; format), leave the port as 8899 and leave the API key field empty. Click on "Connect".</li>
<li>Once connected, paste the pairing payload from Step 2, enable Tor using the slider and click on "Initialize GUI".</li>
<li>Initialization is successful if you see "CLI restart required. Wallet inizialization success". Repeat steps 3-6 if you don't see it.</li>
<li>Restart myNode Whirlpool by clicking on "Restart" button below.</li>
<li>myNode Whirlpool status should now be "Running" and API key should now be visible. This API key is useful if you reset the Whirlpool GUI.</li>
<li>Click on "Retry to connect" if it doesn't connect automatically.</li>
<li>Type in the Samourai mobile wallet passphrase (not the pairing payload) and click on "Sign in".</li>
<li>Enjoy mixing your coins!</li>
</ol>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
from flask import Blueprint, render_template, redirect
from settings import read_ui_settings
from user_management import check_logged_in
from enable_disable_functions import is_whirlpool_enabled, enable_whirlpool, disable_whirlpool
import subprocess
import os
mynode_whirlpool = Blueprint('mynode_whirlpool',__name__)
## Status and color
def get_whirlpool_status():
# Find whirlpool status
whirlpool_status = "Disabled"
whirlpool_status_color = "gray"
whirlpool_initialized = os.path.isfile("/opt/mynode/whirlpool/whirlpool-cli-config.properties")
if is_whirlpool_enabled():
status = os.system("systemctl status whirlpool --no-pager")
if status != 0:
whirlpool_status = "Inactive"
whirlpool_status_color = "red"
else:
if whirlpool_initialized:
whirlpool_status = "Running"
whirlpool_status_color = "green"
else:
whirlpool_status = "Waiting for initialization."
whirlpool_status_color = "yellow"
return whirlpool_status, whirlpool_status_color, whirlpool_initialized
### Page functions
@mynode_whirlpool.route("/whirlpool")
def whirlpool_page():
check_logged_in()
whirlpool_api_key = 'Not found'
try:
whirlpool_api_key = subprocess.check_output("cat /opt/mynode/whirlpool/whirlpool-cli-config* | grep -i cli.Apikey= | cut -c 12-", shell=True)
except:
whirlpool_api_key = 'error'
whirlpool_status, whirlpool_status_color, whirlpool_initialized = get_whirlpool_status()
# Load page
templateData = {
"title": "myNode Whirlpool",
"ui_settings": read_ui_settings(),
"whirlpool_status": whirlpool_status,
"whirlpool_status_color": whirlpool_status_color,
"whirlpool_enabled": is_whirlpool_enabled(),
"whirlpool_initialized": whirlpool_initialized,
"whirlpool_api_key": whirlpool_api_key
}
return render_template('whirlpool.html', **templateData)
@mynode_whirlpool.route("/restart-whirlpool")
def page_toggle_whirlpool():
check_logged_in()
disable_whirlpool()
enable_whirlpool()
return redirect("/whirlpool")