Initial JAM Support

This commit is contained in:
Taylor Helsper 2022-10-16 08:16:04 -05:00
parent dbc7a170d5
commit 09c382cf3c
33 changed files with 486 additions and 105 deletions

View File

@ -0,0 +1,17 @@
server {
listen 62602 ssl;
server_name joinmarketorderbook;
include /etc/nginx/mynode/mynode_ssl_params.conf;
include /etc/nginx/mynode/mynode_ssl_cert_key.conf;
access_log /var/log/nginx/access_joinmarket_orderbook.log;
error_log /var/log/nginx/error_joinmarket_orderbook.log;
location / {
proxy_pass http://127.0.0.1:62601;
include /etc/nginx/mynode/mynode_ssl_proxy_params.conf;
}
}

View File

@ -0,0 +1,25 @@
[Unit]
Description=ob-watcher
[Service]
ExecStartPre=/usr/bin/is_not_shutting_down.sh
ExecStartPre=/usr/bin/wait_on_bitcoin.sh
WorkingDirectory=/home/joinmarket/joinmarket-clientserver/scripts/obwatch
ExecStart=/bin/sh -c '. /home/joinmarket/joinmarket-clientserver/jmvenv/bin/activate && python ob-watcher.py --host=0.0.0.0'
User=joinmarket
Group=joinmarket
Type=simple
TimeoutSec=300
Restart=always
RestartSec=60
# Hardening measures
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target

View File

@ -301,6 +301,14 @@ HiddenServiceDir /var/lib/tor/mynode_sphinx/
HiddenServiceVersion 3
HiddenServicePort 53001 127.0.0.1:53001
# Hidden Service for Joinmarket Orderbook
HiddenServiceDir /var/lib/tor/mynode_obwatcher/
HiddenServiceVersion 3
HiddenServicePort 80 127.0.0.1:62601
HiddenServicePort 443 127.0.0.1:62602
HiddenServicePort 62601 127.0.0.1:62601
HiddenServicePort 62602 127.0.0.1:62602
# Include tor settings for other apps
%include /etc/torrc.d

View File

@ -73,6 +73,10 @@ ufw allow 49393 comment 'allow BTCPay Server-direct HTTPS'
ufw allow 51194 comment 'allow VPN'
ufw allow 61208 comment 'allow Glances'
ufw allow 61209 comment 'allow Glances HTTPS'
ufw allow 62601 comment 'allow JoinMarket Orderbook'
ufw allow 62602 comment 'allow JoinMarket Orderbook HTTPS'
ufw allow 27183 comment 'allow JoinMarket API'
ufw allow 28183 comment 'allow JoinMarket API'
ufw allow from 127.0.0.1 comment 'allow from localhost'
#ufw allow from ::1 comment 'allow from localhost'

View File

@ -663,6 +663,10 @@ if should_install_app "joininbox" ; then
# Install
sudo -u joinmarket bash -c "cd /home/joinmarket/; ${JM_ENV_VARS} ./install.joinmarket.sh --install install" || true
sudo -u joinmarket bash -c "cd /home/joinmarket/; ${JM_ENV_VARS} ./install.joinmarket-api.sh on" || true
# Enable obwatcher service
systemctl enable ob-watcher
echo $JOININBOX_VERSION > $JOININBOX_VERSION_FILE
fi

View File

@ -241,7 +241,7 @@
"While being specifically designed with a mobile first mindset and is available fully implemented within Samourai Wallet, we have made efforts to bring Whirlpool technology to all platforms. Whirlpool is built in to Samourai Wallet and available as a stand alone desktop app available on all platforms."
],
"category": "bitcoin_app",
"short_description": "Mixing Tool",
"short_description": "Mixing Utility",
"app_tile_button_text": "Info",
"app_tile_button_href": "/whirlpool",
"app_tile_running_status_text": "Running",
@ -250,22 +250,22 @@
"homepage_order": 23
},
{
"name": "JoininBox",
"comment": "Keep shortname as joininbox so upgrades work",
"name": "JoinMarket",
"short_name": "joininbox",
"author": {"name": "openoms", "link":""},
"website": {"name": "GitHub", "link": "https://github.com/openoms/joininbox"},
"author": {"name": "AdamISZ", "link":"https://github.com/AdamISZ"},
"website": {"name": "GitHub", "link": "https://github.com/JoinMarket-Org/joinmarket-clientserver"},
"description": [
"A minimalistic, security focused linux environment for JoinMarket with a terminal based graphical menu.",
"JoinMarket is software to create a special kind of bitcoin transaction called a CoinJoin transaction. Its aim is to improve the confidentiality and privacy of bitcoin transactions.",
"A CoinJoin transaction requires other people to take part. The right resources (coins) have to be in the right place, at the right time, in the right quantity. This isn't a software or tech problem, it's an economic problem. JoinMarket works by creating a new kind of market that would allocate these resources in the best way.",
"One group of participants (called market makers) will always be available to take part in CoinJoins at any time. Other participants (called market takers) can create a CoinJoin at any time. The takers pay a fee which incentivizes the makers. A form of smart contract is created, meaning the private keys will never be broadcasted outside of your computer, resulting in virtually zero risk of loss (aside from malware or bugs). As a result of free-market forces the fees will eventually be next to nothing.",
"Widespread use of JoinMarket improves bitcoin's fungibility and privacy. This implementation of JoinMarket also implements PayJoin."
],
"category": "bitcoin_app",
"short_description": "JoinMarket Mixing",
"short_description": "Mixing Utility",
"hide_status_icon": true,
"app_tile_button_text": "Info",
"app_tile_button_href": "/joininbox",
"app_tile_button_href": "/joinmarket",
"can_uninstall": true,
"show_on_homepage": true,
"homepage_order": 24,

View File

@ -77,7 +77,7 @@ CORSPROXY_VERSION=$(get_app_version "$CORSPROXY_VERSION" "corsproxy")
CORSPROXY_VERSION_FILE=/home/bitcoin/.mynode/corsproxy_version
CORSPROXY_LATEST_VERSION_FILE=/home/bitcoin/.mynode/corsproxy_version_latest
JOININBOX_VERSION="v0.7.3"
JOININBOX_VERSION="v0.7.4"
JOININBOX_VERSION=$(get_app_version "$JOININBOX_VERSION" "joininbox")
JOININBOX_VERSION_FILE=/home/bitcoin/.mynode/joininbox_version
JOININBOX_LATEST_VERSION_FILE=/home/bitcoin/.mynode/joininbox_version_latest

View File

@ -0,0 +1,69 @@
{
"name": "Jam",
"short_name": "jam",
"author": {
"name": "",
"link": ""
},
"website": {
"name": "Jam",
"link": "https://jamapp.org/"
},
"category": "bitcoin_app",
"short_description": "Joinmarket UI",
"description": [
"Jam is a graphical user interface for JoinMarket, and while obviously related, is a separate project developed by a separate set of people.",
"Jam is a free and open-source project that aims to improve the financial privacy of yourself and others, without relying on a trusted third party. It was started in 2021 by various volunteers and is still developed and maintained on a volunteer basis. As mentioned above, Jam is a front-end for JoinMarket, a privacy-focused bitcoin software that uses a peer-to-peer marketplace to facilitate collaborative transactions.",
"The goal of Jam is to provide an interface that makes JoinMarket easier to use, and thus more easily accessible for more people.",
"JoinMarket is a special kind of software that is aimed at improving the privacy and fungibility of bitcoin transactions. The main way to improve privacy and fungibility on-chain is via collaborative transactions.",
"A collaborative transaction requires the coordination of multiple parties. The right resources (UTXOs) have to be available in the right quantity at the right time.",
"Consequently, the problem that needs to be solved is not a technological problem, but an economic problem. JoinMarket solves this problem not by central coordination, but by creating a market that allows participants to allocate these resources in the best way, according to their individual needs."
],
"latest_version": "v0.1.1",
"supported_archs": null,
"download_skip": true,
"download_type": "source",
"download_source_url": "not_required",
"download_binary_url": {
"aarch64": "download_url",
"x86_64": "download_url"
},
"install_env_vars": {"DOCKER_IMAGE_NAME": "jam-ui-only:{VERSION}-clientserver-v0.9.8"},
"supports_app_page": true,
"supports_testnet": false,
"http_port": 5020,
"https_port": 5021,
"requires_bitcoin": true,
"requires_docker_image_installation": true,
"requires_electrs": false,
"requires_lightning": false,
"show_on_application_page": true,
"show_on_homepage": true,
"show_on_status_page": true,
"hide_status_icon": false,
"app_tile_name": "Jam",
"app_tile_running_status_text": "Running",
"app_tile_button_text": "Info",
"app_tile_button_href": "/app/jam/info",
"app_page_show_open_button": true,
"app_page_content": [
{
"heading": "Instructions",
"content": [
"JoinMarket is a mixing wallet for Bitcoin that can be used with a web interface via JAM.",
"To get started, you just need to install and enable JAM via the myNode Marketplace.",
"Once installed, click the Open JAM link above or the link on the JAM application page.",
"Enjoy mixing your coins!"
]
}
],
"can_uninstall": true,
"can_reinstall": true,
"can_enable_disable": true,
"is_beta": true,
"is_premium": true,
"homepage_section": "apps",
"homepage_order": 91,
"app_type": "custom",
"sdk_version": 2
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -0,0 +1,42 @@
# jam service
# /etc/systemd/system/jam.service
[Unit]
Description=jam
Wants=www.service docker_images.service
After=www.service docker_images.service
[Service]
WorkingDirectory=/opt/mynode/jam
EnvironmentFile=/mnt/hdd/mynode/settings/.btcrpc_environment
ExecStartPre=/usr/bin/is_not_shutting_down.sh
ExecStartPre=/bin/bash -c 'if [ -f /usr/bin/service_scripts/pre_jam.sh ]; then /bin/bash /usr/bin/service_scripts/pre_jam.sh; fi'
ExecStart=/usr/bin/docker run --rm \
--name jam \
--env JAM_JMWALLETD_HOST="host.docker.internal" \
--env JAM_JMWALLETD_API_PORT="28183" \
--env JAM_JMWALLETD_WEBSOCKET_PORT="27183" \
--env JAM_JMOBWATCH_PORT="62601" \
--env APP_USER="admin" \
--env APP_PASSWORD="bolt" \
--publish "5020:80" \
--add-host=host.docker.internal:host-gateway \
--volume /mnt/hdd/mynode/jam/data:/root/.joinmarket \
jam:latest
ExecStartPost=/bin/bash -c 'if [ -f /usr/bin/service_scripts/post_jam.sh ]; then /bin/bash /usr/bin/service_scripts/post_jam.sh; fi'
ExecStop=/usr/bin/docker stop -t 2 jam
User=bitcoin
Group=bitcoin
Type=simple
TimeoutSec=120
Restart=always
RestartSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=jam
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,17 @@
server {
listen 5021 ssl;
server_name jam;
include /etc/nginx/mynode/mynode_ssl_params.conf;
include /etc/nginx/mynode/mynode_ssl_cert_key.conf;
access_log /var/log/nginx/access_jam.log;
error_log /var/log/nginx/error_jam.log;
location / {
proxy_pass http://127.0.0.1:5020;
include /etc/nginx/mynode/mynode_ssl_proxy_params.conf;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

View File

@ -0,0 +1,31 @@
#!/bin/bash
source /usr/share/mynode/mynode_device_info.sh
source /usr/share/mynode/mynode_app_versions.sh
set -x
set -e
echo "==================== INSTALLING APP ===================="
# The current directory is the app install folder and the app tarball from GitHub
# has already been downloaded and extracted. Any additional env variables specified
# in the JSON file are also present.
#echo "DOCKER NAME: $DOCKER_IMAGE_NAME"
#echo "VERSION: $VERSION"
# Make dir that will be volume mounted to the container
mkdir -p ${STORAGE_FOLDER}/data
# Clear any old images
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep 'jam-') || true
docker rmi jam:latest || true
# Pull latest image
docker pull ghcr.io/joinmarket-webui/$DOCKER_IMAGE_NAME
# Tag latest as "jam:latest"
docker tag ghcr.io/joinmarket-webui/$DOCKER_IMAGE_NAME jam:latest
echo "================== DONE INSTALLING APP ================="

View File

@ -0,0 +1,3 @@
#!/bin/bash
# This will run after launching the application

View File

@ -0,0 +1,3 @@
#!/bin/bash
# This will run prior to launching the application

View File

@ -0,0 +1,12 @@
#!/bin/bash
source /usr/share/mynode/mynode_device_info.sh
source /usr/share/mynode/mynode_app_versions.sh
echo "==================== UNINSTALLING APP ===================="
# The app folder will be removed automatically after this script runs. You may not need to do anything here.
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep 'jam-standalone') || true
echo "================== DONE UNINSTALLING APP ================="

View File

@ -0,0 +1,32 @@
from flask import Blueprint, render_template, redirect
from user_management import check_logged_in
from enable_disable_functions import *
from device_info import *
from application_info import *
from systemctl_info import *
import subprocess
import os
mynode_jam = Blueprint('mynode_jam',__name__)
### Page functions (have prefix /app/<app name/)
@mynode_jam.route("/info")
def jam_page():
check_logged_in()
app = get_application("jam")
app_status = get_application_status("jam")
app_status_color = get_application_status_color("jam")
# Load page
templateData = {
"title": "myNode - " + app["name"],
"ui_settings": read_ui_settings(),
"app_status": app_status,
"app_status_color": app_status_color,
"app": app
}
return render_template('/app/generic_app.html', **templateData)

View File

@ -0,0 +1,3 @@
Custom Jinja templates (HTML files) can be added here for unique application pages
Templates will be available under applications/<short_name>/xyz.html

View File

@ -0,0 +1,54 @@
<!DOCTYPE html lang="en">
<head>
<title>{{ title }}</title>
{% include 'includes/head.html' %}
</head>
<body>
{% include 'includes/logo_header.html' %}
<div class="mynode_top_left_div">
<a href="/"><img class="mynode_nav_icon" src="{{ url_for('static', filename="images/home.png")}}"/></a>
</div>
<div class="main_header">{{app.name}} (custom page - remove)</div>
<br/>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">Status</div>
<div class="info_tile_contents">
<table class="info_table">
<tr>
<th>Status</th>
<td>{{app_status}}</td>
</tr>
<tr>
<th>Actions</th>
<td>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="#">Open</a>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="#">Button A</a>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="#">Button B</a>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="instructions">
<div class="instructions-header">Instructions</div>
<ol class="instructions-steps">
<li>Custom instructions?</li>
</ol>
</div>
<div id="confirm-dialog"></div>
<div id="loading_spinner_overlay" class="loading_spinner_overlay" style="display:none;">
<img id="loading_spinner" class="loading_image" src="{{ url_for('static', filename="images/loading.gif")}}"/>
<br/>
<span id="loading_spinner_message">Loading...</span>
</div>
</body>
</html>

View File

@ -848,7 +848,8 @@ def upgrade_dynamic_apps(short_name="all"):
if app_data["install_env_vars"]:
for key in app_data["install_env_vars"]:
my_env[key] = app_data["install_env_vars"][key]
subprocess.check_output("cd {}; sudo -u {} --preserve-env /bin/bash /usr/bin/service_scripts/install_{}.sh 1>&2".format(app_data["install_folder"], app_data["linux_user"], app_name), shell=True, env=my_env)
# Home dir needs to be set to user so it doesn't inhert root home (causes docker issues)
subprocess.check_output("cd {}; sudo -u {} --preserve-env HOME=/home/{} /bin/bash /usr/bin/service_scripts/install_{}.sh 1>&2".format(app_data["install_folder"], app_data["linux_user"], app_data["linux_user"], app_name), shell=True, env=my_env)
# Mark update latest version if success
log_message(" Upgrade success!")

View File

@ -169,7 +169,7 @@ def update_bitcoin_other_info():
wallet_rpc_connection = AuthServiceProxy("http://%s:%s@127.0.0.1:8332/wallet/%s"%(rpc_user, rpc_pass, wallet_name), timeout=60)
wallet_info = wallet_rpc_connection.getwalletinfo()
wallet_info["can_delete"] = True
if wallet_name == "wallet.dat" or wallet_name == "joinmarket_wallet.dat":
if wallet_name == "wallet.dat":
wallet_info["can_delete"] = False
wallet_data.append(wallet_info)
bitcoin_wallets = wallet_data
@ -313,7 +313,7 @@ def create_default_wallets():
break
if not found:
log_message("Creating new default wallet {}".format(new_wallet))
run_bitcoincli_command("createwallet {}".format(new_wallet))
run_bitcoincli_command("-named createwallet wallet_name={} descriptors=false".format(new_wallet))
run_bitcoincli_command("loadwallet {}".format(new_wallet))

View File

@ -1,6 +1,7 @@
from flask import Blueprint, render_template, redirect, request, flash
from user_management import check_logged_in
from device_info import read_ui_settings
from device_info import read_ui_settings, get_onion_url_for_service
from application_info import *
from systemctl_info import *
from utilities import *
import os
@ -8,7 +9,7 @@ import time
import subprocess
import os
mynode_joininbox = Blueprint('mynode_joininbox',__name__)
mynode_joinmarket = Blueprint('mynode_joinmarket',__name__)
def get_jm_wallets():
wallets = []
@ -17,7 +18,7 @@ def get_jm_wallets():
if os.path.isdir(wallet_folder):
for f in os.listdir(wallet_folder):
wallet_path = wallet_folder + f
if os.path.isfile( wallet_path ):
if os.path.isfile( wallet_path ) and not f.startswith("."):
wallet = {}
wallet["name"] = f
wallets.append(wallet)
@ -26,32 +27,40 @@ def get_jm_wallets():
return wallets
### Page functions
@mynode_joininbox.route("/joininbox")
@mynode_joinmarket.route("/joinmarket")
def joininbox_page():
check_logged_in()
# Load page
templateData = {
"title": "myNode JoininBox / JoinMarket",
"title": "myNode JoinMarket",
"is_jam_installed": is_installed("jam"),
"is_jam_enabled": is_service_enabled("jam"),
"jam_http_port": 5020,
"jam_https_port": 5021,
"jam_tor_address": get_onion_url_for_service("jam"),
"ob_http_port": 62601,
"ob_https_port": 62602,
"ob_tor_address": get_onion_url_for_service("obwatcher"),
"wallets": get_jm_wallets(),
"ui_settings": read_ui_settings(),
}
return render_template('joininbox.html', **templateData)
return render_template('joinmarket.html', **templateData)
@mynode_joininbox.route("/joininbox/download_wallet", methods=["GET"])
def joininbox_download_wallet():
@mynode_joinmarket.route("/joinmarket/download_wallet", methods=["GET"])
def joinmarket_download_wallet():
check_logged_in()
wallet_folder = "/mnt/hdd/mynode/joinmarket/wallets/"
wallet_name = request.args.get('wallet')
if wallet_name is None:
flash("Error finding wallet name!", category="error")
return redirect("/joininbox")
return redirect("/joinmarket")
full_file_path = wallet_folder + wallet_name
if not os.path.isfile( full_file_path ):
time.sleep(3)
flash("Error finding wallet to download!", category="error")
return redirect("/joininbox")
return redirect("/joinmarket")
return download_file(directory=wallet_folder, filename=wallet_name)

View File

@ -6,7 +6,7 @@ from api import mynode_api
from bitcoin import mynode_bitcoin
from whirlpool import mynode_whirlpool
from dojo import mynode_dojo
from joininbox import mynode_joininbox
from joinmarket import mynode_joinmarket
from caravan import mynode_caravan
from sphinxrelay import mynode_sphinxrelay
from pyblock import mynode_pyblock
@ -93,7 +93,7 @@ app.register_blueprint(mynode_lnd)
app.register_blueprint(mynode_api)
app.register_blueprint(mynode_whirlpool)
app.register_blueprint(mynode_dojo)
app.register_blueprint(mynode_joininbox)
app.register_blueprint(mynode_joinmarket)
app.register_blueprint(mynode_caravan)
app.register_blueprint(mynode_sphinxrelay)
app.register_blueprint(mynode_pyblock)

View File

@ -1,82 +0,0 @@
<!DOCTYPE html lang="en">
<head>
<title>{{ title }}</title>
{% include 'includes/head.html' %}
</head>
<body>
{% include 'includes/logo_header.html' %}
<div class="mynode_top_left_div">
<a href="/"><img class="mynode_nav_icon" src="{{ url_for('static', filename="images/home.png")}}"/></a>
</div>
{% include 'includes/message_display.html' %}
<div class="main_header">JoininBox / JoinMarket</div>
<br/>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">Status</div>
<div class="info_tile_contents">Ready</div>
</div>
</div>
{% if wallets is not none and wallets|length > 0 %}
<br/>
<div class="main_header">Wallets</div>
<table class="bitcoin_table">
<thead class="bitcoin_table_header">
<td>Wallet</td>
<td>Actions</td>
</thead>
<tbody>
{% for wallet in wallets %}
<tr>
<td>{{ wallet.name }}</td>
<td>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/joininbox/download_wallet?wallet={{wallet.name|urlencode}}">download</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p style="font-size: 12px; color: gray; text-align: center;">
*These wallets are not your main lightning wallet. These have been created manually or via other applications.<br/>
**Wallet files may contain private keys and sensitive data. Be very cautious when downloading copies.<br/>
***Wallet files may be encrypted and require a password to use.
</p>
<br/>
{% endif %}
<div class="instructions">
<div class="instructions-header">Instructions to setup JoininBox / JoinMarket</div>
<ol class="instructions-steps">
<li>JoinMarket is a mixing wallet for Bitcoin that can be used with a terminal interface via JoininBox.</li>
<li>To get started, you need access to the Linux terminal of your myNode device.</li>
<ul>
<li>This may be advanced for some. Please be careful, myNode is not responsible for lost funds.</li>
<li>A guide to access the Linux terminal is available on mynodebtc.com - <a href="https://mynodebtc.github.io/advanced/linux-terminal.html" target="_blank">guide</a></li>
</ul>
<li>Once you have terminal access, run the following command:</li>
<ul>
<li><pre>sudo mynode-joininbox</pre></li>
</ul>
<li>Enter your myNode password when prompted.</li>
<li>The first time running JoininBox, it may install additional software.</li>
<li>Remember to back up your seed phrases.</li>
<li>Enjoy mixing your coins!</li>
</ol>
<br/><br/>
<!--
<div class="instructions-header">Tips and Notes</div>
<ul style="font-size: 12px;">
<li>Add tips and notes</li>
</ul>
-->
</div>
</body>
</html>

View File

@ -0,0 +1,125 @@
<!DOCTYPE html lang="en">
<head>
<title>{{ title }}</title>
{% include 'includes/head.html' %}
</head>
<body>
{% include 'includes/logo_header.html' %}
<div class="mynode_top_left_div">
<a href="/"><img class="mynode_nav_icon" src="{{ url_for('static', filename="images/home.png")}}"/></a>
</div>
{% include 'includes/message_display.html' %}
<div class="main_header">JoinMarket</div>
<br/>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">Status</div>
<div class="info_tile_contents">Ready</div>
</div>
<div class="info_tile">
<div class="info_tile_header">Actions</div>
<div class="info_tile_contents">
<!-- TODO: Disable button if JAM not enabled-->
<button
class="ui-button ui-widget ui-corner-all mynode_button_small"
onclick="open_app_in_new_tab('{{jam_http_port}}', '{{jam_https_port}}', false, '{{jam_tor_address}}')"
{% if not is_jam_installed or not is_jam_enabled %}
disabled="disabled" title="JAM must be installed and running"
{% endif %}
>Open JAM</button>
<button class="ui-button ui-widget ui-corner-all mynode_button_small" onclick="open_app_in_new_tab('{{ob_http_port}}', '{{ob_https_port}}', false, '{{ob_tor_address}}')">Open Orderbook</button>
</div>
</div>
</div>
{% if wallets is not none and wallets|length > 0 %}
<br/>
<div class="main_header">Wallets</div>
<table class="bitcoin_table">
<thead class="bitcoin_table_header">
<td>Wallet</td>
<td>Actions</td>
</thead>
<tbody>
{% for wallet in wallets %}
<tr>
<td>{{ wallet.name }}</td>
<td>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/joinmarket/download_wallet?wallet={{wallet.name|urlencode}}">download</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p style="font-size: 12px; color: gray; text-align: center;">
*These wallets are not your main lightning wallet. These have been created manually or via other applications.<br/>
**Wallet files may contain private keys and sensitive data. Be very cautious when downloading copies.<br/>
***Wallet files may be encrypted and require a password to use.
</p>
<br/>
{% endif %}
<div class="instructions">
<div class="instructions-header">Instructions to use JoininBox</div>
<ol class="instructions-steps">
<li>JoinMarket is a mixing wallet for Bitcoin that can be used with a web interface via JAM.</li>
<li>To get started, you just need to install and enable JAM via the myNode Marketplace.</li>
<li>Once installed, click the Open JAM link above or the link on the JAM application page.</li>
<li>Enjoy mixing your coins!</li>
</ol>
</div>
<div class="instructions">
<div class="instructions-header">Instructions to use JAM</div>
<ol class="instructions-steps">
<li>JoinMarket is a mixing wallet for Bitcoin that can be used with a terminal interface via JoininBox.</li>
<li>To get started, you need access to the Linux terminal of your myNode device.</li>
<ul>
<li>This may be advanced for some. Please be careful, myNode is not responsible for lost funds.</li>
<li>A guide to access the Linux terminal is available on mynodebtc.com - <a href="https://mynodebtc.github.io/advanced/linux-terminal.html" target="_blank">guide</a></li>
</ul>
<li>Once you have terminal access, run the following command:</li>
<ul>
<li><pre>sudo mynode-joininbox</pre></li>
</ul>
<li>Enter your myNode password when prompted.</li>
<li>The first time running JoininBox, it may install additional software.</li>
<li>Remember to back up your seed phrases.</li>
<li>Enjoy mixing your coins!</li>
</ol>
</div>
<div class="instructions">
<div class="instructions-header">Instructions to use JoinMarket Python Scripts</div>
<ol class="instructions-steps">
<li>JoinMarket is a mixing wallet for Bitcoin that can be used with a terminal interface using Python scripts.</li>
<li>To get started, you need access to the Linux terminal of your myNode device.</li>
<ul>
<li>This may be advanced for some. Please be careful, myNode is not responsible for lost funds.</li>
<li>A guide to access the Linux terminal is available on mynodebtc.com - <a href="https://mynodebtc.github.io/advanced/linux-terminal.html" target="_blank">guide</a></li>
</ul>
<li>Once you have terminal access, run the following command:</li>
<ul>
<li><pre>sudo mynode-joinmarket</pre></li>
</ul>
<li>Enter your myNode password when prompted.</li>
<li>This will change your prompt and you will be running as the joinmarket user with access to the JoinMarket python scripts.</li>
<li>Remember to back up your seed phrases.</li>
<li>Enjoy mixing your coins!</li>
</ol>
<br/>
<div class="instructions-header">Tips and Notes</div>
<ul style="font-size: 12px;">
<li>More information on JoinMarket usage can be found on their <a href="https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/USAGE.md" target="_blank">Github</a>.</li>
</ul>
</div>
</body>
</html>

View File

@ -701,6 +701,10 @@ if [ $IS_RASPI = 1 ] || [ $IS_X86 = 1 ]; then
# Install
sudo -u joinmarket bash -c "cd /home/joinmarket/; ${JM_ENV_VARS} ./install.joinmarket.sh install" || true
sudo -u joinmarket bash -c "cd /home/joinmarket/; ${JM_ENV_VARS} ./install.joinmarket-api.sh on" || true
# Enable obwatcher service
systemctl enable ob-watcher
echo $JOININBOX_VERSION > $JOININBOX_VERSION_FILE
fi