Add Samourai Dojo to MyNode (#143)

+added files
*dojo.service
*mynode_gen_dojo_config.sh
*mynode_post_dojo.sh
*dojo.py
*dojo.html

%modified files
*mynode_firewall.sh
*mynode_post_upgrade.sh
*mynode_stop_critical_services.sh
*bitcoin.conf
*enable_disable_functions.py
*mynode.py
*apps.html

Special thanks to Taylor Helsper for creating MyNode and Merging Dojo

Special thanks to BTCxZelko for getting me started with Dojo and 
assisting with the code. 

Special thanks to Amiga500 for helping with testing.

Co-authored-by: Taylor Helsper <tehelsper@gmail.com>
This commit is contained in:
LightningSats 2020-02-27 20:25:33 -05:00 committed by GitHub
parent a951698224
commit 93281a7c23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 441 additions and 18 deletions

View File

@ -0,0 +1,22 @@
# samourai dojo service
# /etc/systemd/system/dojo.service
[Unit]
Description=Dojo
After=network.target mynode.service
[Service]
Type=forking
RemainAfterExit=yes
WorkingDirectory=/opt/mynode/dojo/docker/my-dojo
ExecStart=/opt/mynode/dojo/docker/my-dojo/dojo.sh start
ExecStop=/opt/mynode/dojo/docker/my-dojo/dojo.sh stop
User=root
Group=root
KillMode=process
TimeoutSec=420
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target

View File

@ -16,8 +16,14 @@ ufw allow 10009 comment 'allow Lightning gRPC'
ufw allow 10080 comment 'allow Lightning REST RPC'
ufw allow 9735 comment 'allow Lightning'
ufw allow 8332 comment 'allow Bitcoin RPC - filtered by rpcallowip'
ufw allow 8333 comment 'allow Bitcoin Mainnet'
ufw allow 18333 comment 'allow Bitcoin Testnet'
ufw allow 8333 comment 'allow Bitcoin mainnet'
ufw allow 18333 comment 'allow Bitcoin testnet'
ufw allow from 172.17.0.0/16 to any port 28332 comment 'allow Dojo zmqrawblock'
ufw allow from 172.28.0.0/16 to any port 28332 comment 'allow Dojo zmqrawblock'
ufw allow from 172.17.0.0/16 to any port 28333 comment 'allow Dojo zmqrawtx'
ufw allow from 172.28.0.0/16 to any port 28333 comment 'allow Dojo zmqrawtx'
ufw allow from 172.17.0.0/16 to any port 28334 comment 'allow Dojo zmqhashblock'
ufw allow from 172.28.0.0/16 to any port 28334 comment 'allow Dojo zmqhashblock'
ufw allow 2222 comment 'allow WebSSH2'
ufw allow 3000 comment 'allow LndHub'
ufw allow 3002 comment 'allow BTC RPC Explorer'

View File

@ -0,0 +1,129 @@
#!/bin/bash
set -x
set -e
source /usr/share/mynode/mynode_config.sh
# replace Dojo bitcoind.conf.tpl with custom conf for MyNode
rm -rf /opt/mynode/dojo/docker/my-dojo/conf/docker-bitcoind.conf.tpl
touch /opt/mynode/dojo/docker/my-dojo/conf/docker-bitcoind.conf.tpl
RPC_PASS=$(cat /mnt/hdd/mynode/settings/.btcrpc_environment | cut -c 18- )
echo "
#########################################
# CONFIGURATION OF BITCOIND CONTAINER #
#########################################
# User account used for rpc access to bitcoind Type: alphanumeric
BITCOIND_RPC_USER=mynode
# Password of user account used for rpc access to bitcoind Type:
# alphanumeric
BITCOIND_RPC_PASSWORD=$RPC_PASS
# Max number of connections to network peers Type: integer
BITCOIND_MAX_CONNECTIONS=16
# Mempool maximum size in MB Type: integer
BITCOIND_MAX_MEMPOOL=600
# Db cache size in MB Type: integer
BITCOIND_DB_CACHE=1024
# Number of threads to service RPC calls Type: integer
BITCOIND_RPC_THREADS=6
# Mempool expiry in hours Defines how long transactions stay in your local
# mempool before expiring Type: integer
BITCOIND_MEMPOOL_EXPIRY=72
# Min relay tx fee in BTC Type: numeric
BITCOIND_MIN_RELAY_TX_FEE=0.00001
#
# EXPERT SETTINGS
#
# EPHEMERAL ONION ADDRESS FOR BITCOIND THIS PARAMETER HAS NO EFFECT IF
# BITCOIND_INSTALL IS SET TO OFF
#
# Generate a new onion address for bitcoind when Dojo is launched
# Activation of this option is recommended for improved privacy. Values: on
# | off
BITCOIND_EPHEMERAL_HS=on
#
# EXPOSE BITCOIND RPC API AND ZMQ NOTIFICATIONS TO EXTERNAL APPS THESE
# PARAMETERS HAVE NO EFFECT IF BITCOIND_INSTALL IS SET TO OFF
#
# Expose the RPC API to external apps Warning: Do not expose your RPC API
# to internet! See BITCOIND_RPC_EXTERNAL_IP Value: on | off
BITCOIND_RPC_EXTERNAL=off
# IP address used to expose the RPC API to external apps This parameter is
# inactive if BITCOIND_RPC_EXTERNAL isn't set to 'on' Warning: Do not
# expose your RPC API to internet! Recommended value:
# linux: 127.0.0.1 macos or windows: IP address of the VM running the
# docker host
# Type: string
BITCOIND_RPC_EXTERNAL_IP=127.0.0.1
#
# INSTALL AND RUN BITCOIND INSIDE DOCKER
#
# Install and run bitcoind inside Docker Set this option to 'off' for using
# a bitcoind hosted outside of Docker (not recommended) Value: on | off
BITCOIND_INSTALL=off
# IP address of bitcoind used by Dojo Set value to 172.28.1.5 if
# BITCOIND_INSTALL is set to 'on' Type: string
BITCOIND_IP=172.28.0.1
# Port of the RPC API Set value to 28256 if BITCOIND_INSTALL is set to 'on'
# Type: integer
BITCOIND_RPC_PORT=8332
# Port exposing ZMQ notifications for raw transactions Set value to 9501 if
# BITCOIND_INSTALL is set to 'on' Type: integer
BITCOIND_ZMQ_RAWTXS=28333
# Port exposing ZMQ notifications for block hashes Set value to 9502 if
# BITCOIND_INSTALL is set to 'on' Type: integer
BITCOIND_ZMQ_BLK_HASH=28334
" | sudo tee -a /opt/mynode/dojo/docker/my-dojo/conf/docker-bitcoind.conf.tpl
# Turn off explorer for MyNode
sed -i 's|EXPLORER_INSTALL=on|EXPLORER_INSTALL=off|' /opt/mynode/dojo/docker/my-dojo/conf/docker-explorer.conf.tpl
# check if configuration files have been previously created and skip if yes
if [ -f /opt/mynode/dojo/docker/my-dojo/conf/docker-node.conf ]; then
echo "File present - skip docker-node.conf"
else
# Modify node.conf to enter random generated passwords
NODE_API_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)
sed -i 's|NODE_API_KEY=.*|NODE_API_KEY='$NODE_API_KEY'|' /opt/mynode/dojo/docker/my-dojo/conf/docker-node.conf.tpl
NODE_ADMIN_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 48 | head -n 1)
sed -i 's|NODE_ADMIN_KEY=.*|NODE_ADMIN_KEY='$NODE_ADMIN_KEY'|' /opt/mynode/dojo/docker/my-dojo/conf/docker-node.conf.tpl
NODE_JWT_SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)
sed -i 's|NODE_JWT_SECRET=.*|NODE_JWT_SECRET='$NODE_JWT_SECRET'|' /opt/mynode/dojo/docker/my-dojo/conf/docker-node.conf.tpl
fi
# check if configuration files have been previously created and skip if yes
if [ -f /opt/mynode/dojo/docker/my-dojo/conf/docker-mysql.conf ]; then
echo "File present - skip docker-mysql.conf"
else
# Modify mysql.conf to enter random generated passwords
MYSQL_ROOT_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)
sed -i 's|MYSQL_ROOT_PASSWORD=.*|MYSQL_ROOT_PASSWORD='$MYSQL_ROOT_PASSWORD'|' /opt/mynode/dojo/docker/my-dojo/conf/docker-mysql.conf.tpl
MYSQL_USER=mynode
sed -i 's|MYSQL_USER=.*|MYSQL_USER='$MYSQL_USER'|' /opt/mynode/dojo/docker/my-dojo/conf/docker-mysql.conf.tpl
MYSQL_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)
sed -i 's|MYSQL_PASSWORD=.*|MYSQL_PASSWORD='$MYSQL_PASSWORD'|' /opt/mynode/dojo/docker/my-dojo/conf/docker-mysql.conf.tpl
fi
# Modify for Raspbian devices
if [ $IS_RASPI = 1 ]; then
# Modify mysql Dockerfile for Raspbian devices
sed -i 's|FROM.*|FROM hypriot/rpi-mysql:latest|' /opt/mynode/dojo/docker/my-dojo/mysql/Dockerfile
# Modify Tor Dockerfile for ARMv6/7 devices
sed -i 's|ENV GOLANG_ARCHIVE.*|ENV GOLANG_ARCHIVE go1.13.6.linux-armv6l.tar.gz|' /opt/mynode/dojo/docker/my-dojo/tor/Dockerfile
sed -i 's|ENV GOLANG_SHA256.*|ENV GOLANG_SHA256 37a1a83e363dcf146a67fa839d170fd1afb13009585fdd493d0a3370fbe6f785|' /opt/mynode/dojo/docker/my-dojo/tor/Dockerfile
fi
# Modify for Rock64 devices
if [ $IS_ROCK64 = 1 ] || [ $IS_ROCKPRO64 = 1 ]; then
# Modify mysql Dockerfile for Rock64 devices
sed -i 's|FROM.*|FROM mariadb:latest|' /opt/mynode/dojo/docker/my-dojo/mysql/Dockerfile
# Modify Tor Dockerfile for ARMv8 devices
sed -i 's|ENV GOLANG_ARCHIVE.*|ENV GOLANG_ARCHIVE go1.13.6.linux-arm64.tar.gz|' /opt/mynode/dojo/docker/my-dojo/tor/Dockerfile
sed -i 's|ENV GOLANG_SHA256.*|ENV GOLANG_SHA256 0a18125c4ed80f9c3045cf92384670907c4796b43ed63c4307210fe93e5bbca5|' /opt/mynode/dojo/docker/my-dojo/tor/Dockerfile
fi

View File

@ -0,0 +1,35 @@
#!/bin/bash
set -e
sleep 10s #dojo needs time to start before passing next line
# initalize mysql db (REQUIRED TO START MYSQL)
counter=0
target=50
isRunning=""
MYSQL_DATABASE=samourai-main
# check on loop if mysql db is running. when running initialize
while [ $counter != $target ]
do
source /opt/mynode/dojo/docker/my-dojo/conf/docker-mysql.conf || exit 0
# Check if dojo mysql db is running (check the db container)
isRunning=$(docker inspect --format="{{.State.Running}}" db)
if [ $isRunning == "true" ]; then
sleep 20s
docker exec -i db bash -c "mysql -h db -u root -p$MYSQL_ROOT_PASSWORD $MYSQL_DATABASE" </opt/mynode/dojo/db-scripts/1_db.sql
echo "dojo mysql db initalized"
sleep 5s
#Stop dojo after install/update and initalization is complete
cd /opt/mynode/dojo/docker/my-dojo
sudo ./dojo.sh stop
counter=$target
else
echo "waiting to initalize dojo mysql db - retrying $[ $target-$counter ] more times"
counter=$(( $counter + 1 ))
sleep 30s
fi
done || exit 0

View File

@ -308,6 +308,47 @@ if [ "$CURRENT" != "$WHIRLPOOL_UPGRADE_URL" ]; then
echo $WHIRLPOOL_UPGRADE_URL > $WHIRLPOOL_UPGRADE_URL_FILE
fi
# Install Dojo
DOJO_VERSION="v1.4.1"
DOJO_UPGRADE_URL=https://github.com/Samourai-Wallet/samourai-dojo/archive/$DOJO_VERSION.tar.gz
DOJO_UPGRADE_URL_FILE=/home/bitcoin/.mynode/.dojo_url
CURRENT=""
INSTALL=true
if [ -f $DOJO_UPGRADE_URL_FILE ]; then
INSTALL=false
CURRENT=$(cat $DOJO_UPGRADE_URL_FILE)
fi
if [ "$CURRENT" != "$DOJO_UPGRADE_URL" ]; then
sudo systemctl stop bitcoind
sudo mkdir -p /opt/mynode/.dojo
sudo mkdir -p /opt/mynode/dojo
sudo rm -rf /opt/mynode/.dojo/*
cd /opt/mynode/.dojo
sudo wget -O dojo.tar.gz $DOJO_UPGRADE_URL
sudo tar -zxvf dojo.tar.gz
sudo cp -r samourai-dojo*/* /opt/mynode/dojo
cd /usr/bin
sudo rm -rf /opt/mynode/.dojo/*
# Configure Dojo for MyNode
sudo ./mynode_gen_dojo_config.sh
# Run Dojo Install or Upgrade
cd /opt/mynode/dojo/docker/my-dojo
if [ "$INSTALL" = "true" ]; then
echo 'y' | sudo ./dojo.sh install &
else
echo 'y' | sudo ./dojo.sh upgrade &
fi
#Check for install/upgrade to finish to initialize Dojo mysql db
cd /usr/bin
sudo ./mynode_post_dojo.sh
echo $DOJO_UPGRADE_URL > $DOJO_UPGRADE_URL_FILE
fi
# Upgrade RTL
RTL_VERSION="v0.6.7"
RTL_UPGRADE_URL=https://github.com/Ride-The-Lightning/RTL/archive/$RTL_VERSION.tar.gz

View File

@ -8,12 +8,14 @@ systemctl stop glances
systemctl stop rtl
systemctl stop webssh2
systemctl stop whirlpool
systemctl stop dojo
systemctl stop btcpayserver
# Stop core services
systemctl stop electrs
systemctl stop lnd
systemctl stop quicksync
systemctl stop bitcoind
sync
sync

View File

@ -20,13 +20,15 @@ rpcauth=mynode:7b7e11c032ddd3fc3835e4e463afd305$6c6a32bbd08cb1b67b5ea89b66865c5c
rpcport=8332
rpcbind=0.0.0.0
rpcbind=172.17.0.1
rpcbind=172.28.0.1
rpcallowip=127.0.0.1
rpcallowip=10.0.0.0/8
rpcallowip=172.0.0.0/8
rpcallowip=192.0.0.0/8
zmqpubrawblock=tcp://127.0.0.1:28332
zmqpubrawtx=tcp://127.0.0.1:28333
zmqpubrawblock=tcp://0.0.0.0:28332
zmqpubrawtx=tcp://0.0.0.0:28333
zmqpubhashblock=tcp://0.0.0.0:28334
# myNode Optimizations

View File

@ -0,0 +1,71 @@
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_dojo_enabled, enable_dojo, disable_dojo
import subprocess
import os
mynode_dojo = Blueprint('mynode_dojo',__name__)
## Status and color
def get_dojo_status():
# Find dojo status
dojo_status = "Disabled"
dojo_status_color = "gray"
try:
dojo_initialized = subprocess.check_output("docker inspect --format={{.State.Running}} db", shell=True)
dojo_initialized = dojo_initialized.strip()
except:
dojo_initialized = ""
if is_dojo_enabled():
if dojo_initialized != "false":
dojo_status = "Running"
dojo_status_color = "green"
else:
dojo_status = "Issue Starting"
dojo_status_color = "red"
dojo_initialized = ""
return dojo_status, dojo_status_color, dojo_initialized
### Page functions
@mynode_dojo.route("/dojo")
def dojo_page():
check_logged_in()
NODE_ADMIN_KEY = 'Not found'
try:
NODE_ADMIN_KEY = subprocess.check_output("cat /opt/mynode/dojo/docker/my-dojo/conf/docker-node.conf | grep -i NODE_ADMIN_KEY= | cut -c 16-", shell=True)
NODE_ADMIN_KEY = NODE_ADMIN_KEY.strip()
except:
NODE_ADMIN_KEY = 'error'
DOJO_V3_ADDR = 'Not found'
try:
DOJO_V3_ADDR = subprocess.check_output("docker exec tor cat /var/lib/tor/hsv3dojo/hostname", shell=True)
PAGE = '/admin'
DOJO_V3_ADDR = DOJO_V3_ADDR.strip() + PAGE
except:
DOJO_V3_ADDR = 'error'
dojo_status, dojo_status_color, dojo_initialized = get_dojo_status()
# Load page
templateData = {
"title": "myNode Dojo",
"ui_settings": read_ui_settings(),
"dojo_status": dojo_status,
"dojo_status_color": dojo_status_color,
"dojo_enabled": is_dojo_enabled(),
"dojo_initialized": dojo_initialized,
"NODE_ADMIN_KEY": NODE_ADMIN_KEY,
"DOJO_V3_ADDR": DOJO_V3_ADDR
}
return render_template('dojo.html', **templateData)
@mynode_dojo.route("/restart-dojo")
def page_toggle_dojo():
check_logged_in()
disable_dojo()
enable_dojo()
return redirect("/dojo")

View File

@ -128,4 +128,15 @@ def enable_whirlpool():
def disable_whirlpool():
os.system("systemctl stop whirlpool --no-pager")
os.system("systemctl disable whirlpool --no-pager")
os.system("systemctl disable whirlpool --no-pager")
def is_dojo_enabled():
return is_service_enabled("dojo")
def enable_dojo():
os.system("systemctl enable dojo --no-pager")
os.system("systemctl start dojo --no-pager")
def disable_dojo():
os.system("systemctl stop dojo --no-pager")
os.system("systemctl disable dojo --no-pager")

View File

@ -5,6 +5,7 @@ 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 dojo import mynode_dojo, get_dojo_status
from tor import mynode_tor
from vpn import mynode_vpn
from electrum_server import *
@ -43,6 +44,7 @@ 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_dojo)
app.register_blueprint(mynode_tor)
app.register_blueprint(mynode_electrum_server)
app.register_blueprint(mynode_vpn)
@ -376,6 +378,9 @@ def index():
# Find whirlpool status
whirlpool_status, whirlpool_status_color, whirlpool_initialized = get_whirlpool_status()
# Find dojo status
dojo_status, dojo_status_color, dojo_initialized = get_dojo_status()
# Check for new version of software
upgrade_available = False
current = get_current_version()
@ -419,6 +424,10 @@ def index():
"whirlpool_status_color": whirlpool_status_color,
"whirlpool_enabled": is_whirlpool_enabled(),
"whirlpool_initialized": whirlpool_initialized,
"dojo_status": dojo_status,
"dojo_status_color": dojo_status_color,
"dojo_enabled": is_dojo_enabled(),
"dojo_initialized": dojo_initialized,
"product_key_skipped": pk_skipped,
"product_key_error": pk_error,
"fsck_error": has_fsck_error(),
@ -543,6 +552,15 @@ def page_toggle_whirlpool():
enable_whirlpool()
return redirect("/")
@app.route("/toggle-dojo")
def page_toggle_dojo():
check_logged_in()
if is_dojo_enabled():
disable_dojo()
else:
enable_dojo()
return redirect("/")
@app.route("/login", methods=["GET","POST"])
def page_login():
templateData = {

View File

@ -0,0 +1,71 @@
<!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 Dojo</div>
</br>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">Status</div>
<div class="info_tile_contents">{{dojo_status}}</div>
</div>
{% if dojo_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-dojo">Restart</a>
</div>
</div>
{% endif %}
</div>
</br>
<div class="app_tile_row">
{% if dojo_enabled and dojo_initialized %}
<div class="info_tile">
<div class="info_tile_header">Dojo V3 Onion Address</div>
<div class="info_tile_contents">{{DOJO_V3_ADDR}}</div>
</div>
</div>
</br>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">NODE_ADMIN_KEY</div>
<div class="info_tile_contents">{{NODE_ADMIN_KEY}}</div>
</div>
{% endif %}
</div>
<div class="instructions">
<div class="instructions-header"><u><strong>Instructions to CONNECT Samourai Wallet to Dojo</u></strong></div>
</br>
<ol class="instructions-steps">
<li>To complete the next steps, Samourai Dojo's Status must be "Running".</li>
<li>You will also need Tor Browser, Dojo's V3 Onion Address and your NODE_ADMIN_KEY to access the Dojo Maintenance Tool.</li>
<li>Open Tor Browser and copy & paste the V3 Onion Address provided above into the Tor Browser's address bar.</li>
<li>You should now be on the login page of the Dojo Maintenance Tool.</li>
<li>Copy your NODE_ADMIN_KEY into the input box and press enter.</li>
<li>Once authenticated, you will be brought to the "Pairing" tab.</li>
<li>In Samourai Wallet, go to the main wallet creation screen and select "Connect to existing Dojo" to connect to your Dojo back-end.</li>
<li>Now scan the "PAIR YOUR WALLET WITH YOUR DOJO" QR Code.</li>
<li><em>**NOTE**</em> - Currently, you must create a new wallet to pair to your Dojo. To do this, you must first delete your current wallet.<em>**See Instructions Below**</em></li>
<li>Check your setup by going to "Networking" in your Samourai Wallet, you should see "Dojo Full Node" enabled with a green dot next to it.</li>
<li>Congratulations, you are now your own bank!!</li>
</ol>
</br>
<div class="instructions-header"><u><strong>Instructions to DELETE Samourai Wallet</u></strong></div>
</br>
<ol class="instructions-steps">
<li><em>**NOTE**</em> - If you are going to delete your wallet, make sure you have your seed phrase and passphrase handy so you can restore your wallet after pairing.</li>
<li>To delete your wallet, go to Settings -> Wallet -> "Secure erase wallet".</li>
<li>On the main screen, to create a new wallet select "Connect to existing Dojo" and scan your QR Code.</li>
<li>Once connected, press back and now go to the option "Import external wallet" and restore your wallet using your seed phrase.</li>
</ol>
</div>
</body>
</html>

View File

@ -43,6 +43,23 @@
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ btcrpcexplorer_status_color }}"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/btc_rpc_explorer.png")}}"/></div>
<div class="app_title">Explorer</div>
<div class="app_status">{{ btcrpcexplorer_status }}</div>
<div class="app_contents">
{% if btcrpcexplorer_enabled %}
{% if btcrpcexplorer_ready %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="btcrpcexplorer">Explorer</a>
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="toggle-btcrpcexplorer">Disable</a>
{% endif %}
{% else %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="toggle-btcrpcexplorer">Enable</a>
{% endif %}
</div>
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ lndconnect_status_color }}"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/lndconnect.png")}}"/></div>
@ -71,19 +88,17 @@
</div>
-->
<div class="app_tile">
<div class="app_status_icon {{ btcrpcexplorer_status_color }}"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/btc_rpc_explorer.png")}}"/></div>
<div class="app_title">Explorer</div>
<div class="app_status">{{ btcrpcexplorer_status }}</div>
<div class="app_status_icon {{ dojo_status_color }}"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/samourai.png")}}"/></div>
<div class="app_title">Dojo</div>
<div class="app_status">{{ dojo_status }}</div>
<div class="app_contents">
{% if btcrpcexplorer_enabled %}
{% if btcrpcexplorer_ready %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="btcrpcexplorer">Explorer</a>
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="toggle-btcrpcexplorer">Disable</a>
{% endif %}
{% else %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="toggle-btcrpcexplorer">Enable</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/dojo">
{% if dojo_initialized %}Info{% else %}Info{% endif %}
</a>
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/toggle-dojo">
{% if dojo_enabled %}Disable{% else %}Enable{% endif %}
</a>
</div>
</div>
<div class="app_tile">