diff --git a/accounts/support-rest-api.js b/accounts/support-rest-api.js index 50ddbeb..434d849 100644 --- a/accounts/support-rest-api.js +++ b/accounts/support-rest-api.js @@ -4,6 +4,7 @@ */ 'use strict' +const fs = require('fs') const validator = require('validator') const bodyParser = require('body-parser') const errors = require('../lib/errors') @@ -68,6 +69,13 @@ class SupportRestApi { HttpServer.sendAuthError ) + this.httpServer.app.get( + `/${keys.prefixes.support}/pairing/explorer`, + authMgr.checkHasAdminProfile.bind(authMgr), + this.getPairingExplorer.bind(this), + HttpServer.sendAuthError + ) + this.httpServer.app.get( `/${keys.prefixes.support}/pairing`, authMgr.checkHasAdminProfile.bind(authMgr), @@ -299,6 +307,39 @@ class SupportRestApi { } } + /** + * Get pairing info for the local block explorer + */ + async getPairingExplorer(req, res) { + try { + let url = '' + if (process.env.EXPLORER_INSTALL == 'on') { + try { + url = fs.readFileSync('/var/lib/tor/hsv3explorer/hostname', 'utf8') + url = url.replace('\n', '') + } catch(e) { + Logger.error(e, 'SupportRestApi.getPairing() : Cannot read explorer onion address') + } + } + const ret = { + 'pairing': { + 'type': 'explorer.btcRpcExplorer', + 'url': url, + 'key': process.env.EXPLORER_KEY + } + } + HttpServer.sendRawData(res, JSON.stringify(ret, null, 2)) + } catch(e) { + const ret = { + status: 'error' + } + Logger.error(e, 'SupportRestApi.getPairingExplorer() : Support pairing error') + HttpServer.sendError(res, JSON.stringify(ret, null, 2)) + } finally { + debugApi && Logger.info(`Completed GET /pairing/explorer`) + } + } + /** * Validate arguments related to GET xpub info requests * @param {object} req - http request object diff --git a/doc/DOCKER_setup.md b/doc/DOCKER_setup.md index 3d91223..5bca766 100644 --- a/doc/DOCKER_setup.md +++ b/doc/DOCKER_setup.md @@ -3,8 +3,9 @@ MyDojo is a set of Docker containers providing a full Samourai backend composed of: * a bitcoin full node accessible as an ephemeral Tor hidden service, * a backend database, -* a backend modules with an API accessible as a static Tor hidden service, -* a maintenance tool accessible through a Tor web browser. +* backend modules with an API accessible as a static Tor hidden service, +* a maintenance tool accessible through a Tor web browser, +* a block explorer ([BTC RPC Explorer](https://github.com/janoside/btc-rpc-explorer)) accessible as a static Tor hidden service. ## Table of Content ## @@ -15,6 +16,7 @@ MyDojo is a set of Docker containers providing a full Samourai backend composed - [Upgrade procedure](#upgrade) - [Dojo shell script](#shell_script) - [Dojo maintenance tool](#maintenance_tool) +- [Block explorer](#explorer) - [Pairing your wallet to your Dojo](#pairing) - [Network connections](#network) @@ -38,21 +40,23 @@ MyDojo is a set of Docker containers providing a full Samourai backend composed Host machine | (Tor hidden services) ______________________________ | _____________________________ | | | - | ------------------- | + | ------------------- dmznet | | | Tor Container | | | ------------------- | | | | | | ------------------- | | - | | Nginx Container | | dmznet | + | | Nginx Container | | | | ------------------- | | - |- - - - - - - - - - - | - - - - - - - | - - - - - - - - - - - | - | -------------------- -------------------- | + |- - - - - - - - - - - | - - -|- - - - | - - - - - - - - - - - | + | -------------------- | -------------------- | | | Nodejs Container | ------ | Bitcoind Container | | + | -------------------- | -------------------- | + | | | | | + | -------------------- | -------------------- | + | | MySQL Container | ---- | BTC RPC Explorer | | | -------------------- -------------------- | - | | | - | ------------------- | - | | MySQL Container | dojonet | - | ------------------- | + | | + | dojonet | |______________________________________________________________| @@ -73,11 +77,13 @@ MyDojo is a set of Docker containers providing a full Samourai backend composed ## Configuration files ## -Each new release of Dojo is packaged with 4 template files stored in the `/docker/my-dojo/conf` directory: +Each new release of Dojo is packaged with 6 template files stored in the `/docker/my-dojo/conf` directory: - docker-common.conf.tpl - docker-bitcoin.conf.tpl +- docker-explorer.conf.tpl - docker-mysql.conf.tpl - docker-node.conf.tpl +- docker-tor.conf.tpl These template files define default values for configuration options of your Dojo. @@ -127,6 +133,7 @@ This procedure allows to install a new Dojo from scratch. * `MYSQL_ROOT_PASSWORD` = password protecting the root account of MySQL, * `MYSQL_USER` = login of the account used to access the database of your Dojo, * `MYSQL_PASSWORD` = password of the account used to access the database of your Dojo. + Note: These values can't be changed after the first installation. * Edit docker-node.conf.tpl and provide a new value for the following parameters: * `NODE_API_KEY` = API key which will be required from your Samourai Wallet / Sentinel for its interactions with the API of your Dojo, @@ -134,6 +141,11 @@ This procedure allows to install a new Dojo from scratch. * `NODE_JWT_SECRET` = secret used by your Dojo for the initialization of a cryptographic key signing Json Web Tokens. These parameters will protect the access to your Dojo. Be sure to provide alphanumeric values with enough entropy. + * Edit docker-explorer.conf.tpl and provide a new value for the following parameter: + * `EXPLORER_KEY` = password that will be required to access the block explorer, + * If you want to deactivate the block explorer, set the value of `EXPLORER_INSTALL` to `off`. + See this [section](#explorer) for more details about the block explorer. + * Dojo provides a few additional settings for advanced setups: * static onion address for your full node, * bitcoind RPC API exposed to external apps, @@ -151,7 +163,7 @@ This procedure allows to install a new Dojo from scratch. ./dojo.sh install ``` -Docker and Docker Compose are going to build the images and containers of your Dojo. This operation will take a few minutes (download and setup of all required software components). After completion, your Dojo will be launched and will begin the initialization of the full node (Bitcoin Initial Block Download and syncing of the database). This step will take several hours/days according to the specs of your machine. Be patient. Use CTRL+C to stop the display of the full logs. +Docker and Docker Compose are going to build the images and containers of your Dojo. This operation will take several minutes (download and setup of all required software components). After completion, your Dojo will be launched and will begin the initialization of the full node (Bitcoin Initial Block Download and syncing of the database). This step will take several hours/days according to the specs of your machine. Be patient. Use CTRL+C to stop the display of the full logs. * Monitor the progress made for the initialization of the database with this command displaying the logs of the tracker @@ -163,7 +175,7 @@ Docker and Docker Compose are going to build the images and containers of your D Exit the logs with CTRL+C when the syncing of the database has completed. -* Retrieve the Tor onion addresses (v2 and v3) of the API of your Dojo +* Retrieve the Tor onion addresses (v3) of the API and block explorer of your Dojo ``` ./dojo.sh onion @@ -198,7 +210,7 @@ This procedure allows to upgrade your Dojo with a new version. Docker and Docker Compose are going to build new images and containers for your Dojo. After completion, the updated version of your Dojo will be launched automatically. -Note: The upgrade process will override all manual modifications of the files stored under the `` directory with an exception for the three configuration files stored in the `/docker/my-dojo/conf` directory. +Note: The upgrade process will override all manual modifications of the files stored under the `` directory with an exception for the configuration files stored in the `/docker/my-dojo/conf` directory. @@ -231,13 +243,14 @@ Available commands: dojo.sh logs tracker : display the logs of the Tracker (nodejs) dojo.sh logs pushtx : display the logs of the pushTx API (nodejs) dojo.sh logs pushtx-orchest : display the logs of the Orchestrator (nodejs) + dojo.sh logs explorer : display the logs of the Explorer - Available options (for api, tracker, pushtx and pushtx-orchest modules): + Available options (for api, tracker, pushtx, pushtx-orchest and explorer modules): -d [VALUE] : select the type of log to be displayed. VALUE can be output (default) or error. -n [VALUE] : display the last VALUE lines - onion Display the Tor onion address allowing your wallet to access your Dojo. + onion Display the Tor onion addresses allowing to access the API, maintenance tool and block explorer of your Dojo. restart Restart your Dojo. @@ -264,6 +277,27 @@ The maintenance tool requires that you allow javascript for the site. Sign in with the value entered for `NODE_ADMIN_KEY`. + + +## Block explorer ## + +A block explorer ([BTC RPC Explorer](https://github.com/janoside/btc-rpc-explorer)) is accessible through your Tor browser. + +You can retrieve the onion address of the block explorer with the command + +``` +./dojo.sh onion +``` + +Sign in with a login (can be any value) and the password set in your Dojo configuration (value entered for `EXPLORER_KEY`). + +Notes: + +* Current version doesn't support the display of detailed information for a Bitcoin address, + +* Calls to the RPC API of your bitcoind are deactivated. + + ## Pairing your wallet to your Dojo ## @@ -272,11 +306,20 @@ Once the database has finished syncing, you can pair your Samourai Wallet with y 1. Open the maintenance tool in a Tor browser (Tor v3 onion address) and sign in with your admin key. -2. Get your smartphone and launch the Samourai Wallet app. Scan the QRCode displayed in the "Pairing" tab of the maintenance tool. +2. Get your smartphone and launch the Samourai Wallet app. Scan the first QRCode displayed in the "Pairing" tab of the maintenance tool. If you experience any problems when pairing, try re-installing the app and select "Connect to existing Dojo" from the [⋮] menu. +## Pairing your wallet to your local block explorer (coming "soon") ## + +You can pair your Samourai Wallet with your local block explorer in 2 steps: + +1. Open the maintenance tool in a Tor browser (Tor v3 onion address) and sign in with your admin key. + +2. Get your smartphone and launch the Samourai Wallet app. Scan the second QRCode displayed in the "Pairing" tab of the maintenance tool. + + ## Network connections ## @@ -287,6 +330,8 @@ If OXT is selected as the default source for imports, OXT clearnet API is access The maintenance tool is accessed as a Tor hidden service (static onion address). +The block explorer is accessed as a Tor hidden service (static onion address). + The Bitcoin node only allows incoming connections from Tor (ephemeral onion address). The Bitcoin node attempts outgoing connections to both Tor and clearnet nodes (through the Tor local proxy). diff --git a/docker/my-dojo/.env b/docker/my-dojo/.env index 388973b..b36210f 100644 --- a/docker/my-dojo/.env +++ b/docker/my-dojo/.env @@ -13,9 +13,10 @@ COMPOSE_CONVERT_WINDOWS_PATHS=1 DOJO_VERSION_TAG=1.4.0 DOJO_DB_VERSION_TAG=1.1.0 DOJO_BITCOIND_VERSION_TAG=1.3.0 -DOJO_NODEJS_VERSION_TAG=1.3.0 -DOJO_NGINX_VERSION_TAG=1.3.0 -DOJO_TOR_VERSION_TAG=1.2.0 +DOJO_NODEJS_VERSION_TAG=1.4.0 +DOJO_NGINX_VERSION_TAG=1.4.0 +DOJO_TOR_VERSION_TAG=1.3.0 +DOJO_EXPLORER_VERSION_TAG=1.0.0 ######################################### diff --git a/docker/my-dojo/conf/docker-explorer.conf.tpl b/docker/my-dojo/conf/docker-explorer.conf.tpl new file mode 100644 index 0000000..6ad0771 --- /dev/null +++ b/docker/my-dojo/conf/docker-explorer.conf.tpl @@ -0,0 +1,16 @@ +######################################### +# CONFIGURATION OF EXPLORER CONTAINER +######################################### + + +# Install and run a block explorer inside Dojo (recommended) +# Value: on | off +EXPLORER_INSTALL=on + + +# Password required for accessing the block explorer +# (login can be anything) +# Keep this password secret! +# Provide a value with a high entropy! +# Type: alphanumeric +EXPLORER_KEY=myExplorerPassword diff --git a/docker/my-dojo/docker-compose.yaml b/docker/my-dojo/docker-compose.yaml index eb2ef0e..8753b72 100644 --- a/docker/my-dojo/docker-compose.yaml +++ b/docker/my-dojo/docker-compose.yaml @@ -30,6 +30,7 @@ services: - ./conf/docker-common.conf - ./conf/docker-mysql.conf - ./conf/docker-bitcoind.conf + - ./conf/docker-explorer.conf - ./conf/docker-node.conf restart: on-failure command: "/home/node/app/wait-for-it.sh db:3306 --timeout=720 --strict -- /home/node/app/restart.sh" @@ -39,6 +40,7 @@ services: - "8082" volumes: - data-nodejs:/data + - data-tor:/var/lib/tor depends_on: - db networks: @@ -57,6 +59,7 @@ services: command: "/wait-for node:8080 --timeout=720 -- nginx" expose: - "80" + - "9080" volumes: - data-nginx:/data depends_on: @@ -74,6 +77,7 @@ services: context: ./tor env_file: - ./.env + - ./conf/docker-explorer.conf - ./conf/docker-tor.conf restart: on-failure command: /restart.sh diff --git a/docker/my-dojo/dojo.sh b/docker/my-dojo/dojo.sh index 54e9f6d..fd17f41 100755 --- a/docker/my-dojo/dojo.sh +++ b/docker/my-dojo/dojo.sh @@ -15,6 +15,7 @@ source_file() { # Source config files source_file "$DIR/conf/docker-bitcoind.conf" +source_file "$DIR/conf/docker-explorer.conf" source_file "$DIR/conf/docker-common.conf" source_file "$DIR/.env" @@ -33,6 +34,10 @@ select_yaml_files() { fi fi + if [ "$EXPLORER_INSTALL" == "on" ]; then + yamlFiles="$yamlFiles -f $DIR/overrides/explorer.install.yaml" + fi + # Return yamlFiles echo "$yamlFiles" } @@ -113,6 +118,7 @@ uninstall() { docker image rm samouraiwallet/dojo-db:"$DOJO_DB_VERSION_TAG" docker image rm samouraiwallet/dojo-bitcoind:"$DOJO_BITCOIND_VERSION_TAG" + docker image rm samouraiwallet/dojo-explorer:"$DOJO_EXPLORER_VERSION_TAG" docker image rm samouraiwallet/dojo-nodejs:"$DOJO_NODEJS_VERSION_TAG" docker image rm samouraiwallet/dojo-nginx:"$DOJO_NGINX_VERSION_TAG" docker image rm samouraiwallet/dojo-tor:"$DOJO_TOR_VERSION_TAG" @@ -135,6 +141,7 @@ clean() { docker image prune del_images_for samouraiwallet/dojo-db "$DOJO_DB_VERSION_TAG" del_images_for samouraiwallet/dojo-bitcoind "$DOJO_BITCOIND_VERSION_TAG" + del_images_for samouraiwallet/dojo-explorer "$DOJO_EXPLORER_VERSION_TAG" del_images_for samouraiwallet/dojo-nodejs "$DOJO_NODEJS_VERSION_TAG" del_images_for samouraiwallet/dojo-nginx "$DOJO_NGINX_VERSION_TAG" del_images_for samouraiwallet/dojo-tor "$DOJO_TOR_VERSION_TAG" @@ -170,9 +177,13 @@ upgrade() { # Display the onion address onion() { + if [ "$EXPLORER_INSTALL" == "on" ]; then + V3_ADDR_EXPLORER=$( docker exec -it tor cat /var/lib/tor/hsv3explorer/hostname ) + echo "Explorer hidden service address (v3) = $V3_ADDR_EXPLORER" + fi + V2_ADDR=$( docker exec -it tor cat /var/lib/tor/hsv2dojo/hostname ) V3_ADDR=$( docker exec -it tor cat /var/lib/tor/hsv3dojo/hostname ) - echo "API hidden service address (v3) = $V3_ADDR" echo "API hidden service address (v2) = $V2_ADDR" @@ -196,6 +207,14 @@ logs_node() { fi } +logs_explorer() { + if [ $3 -eq 0 ]; then + docker exec -ti explorer tail -f /data/logs/$1-$2.log + else + docker exec -ti explorer tail -n $3 /data/logs/$1-$2.log + fi +} + logs() { source_file "$DIR/conf/docker-bitcoind.conf" source_file "$DIR/conf/docker-common.conf" @@ -222,12 +241,18 @@ logs() { api | pushtx | pushtx-orchest | tracker ) logs_node $1 $2 $3 ;; + explorer ) + logs_explorer $1 $2 $3 + ;; * ) yamlFiles=$(select_yaml_files) services="nginx node tor db" if [ "$BITCOIND_INSTALL" == "on" ]; then services="$services bitcoind" fi + if [ "$EXPLORER_INSTALL" == "on" ]; then + services="$services explorer" + fi eval "docker-compose $yamlFiles logs --tail=0 --follow $services" ;; esac @@ -259,8 +284,9 @@ help() { echo " dojo.sh logs tracker : display the logs of the Tracker (nodejs)" echo " dojo.sh logs pushtx : display the logs of the pushTx API (nodejs)" echo " dojo.sh logs pushtx-orchest : display the logs of the pushTx Orchestrator (nodejs)" + echo " dojo.sh logs explorer : display the logs of the Explorer" echo " " - echo " Available options (only available for api, tracker, pushtx and pushtx-orchest modules):" + echo " Available options (only available for api, tracker, pushtx, pushtx-orchest and explorer modules):" echo " -d [VALUE] : select the type of log to be displayed." echo " VALUE can be output (default) or error." echo " -n [VALUE] : display the last VALUE lines" diff --git a/docker/my-dojo/explorer/Dockerfile b/docker/my-dojo/explorer/Dockerfile new file mode 100644 index 0000000..081460a --- /dev/null +++ b/docker/my-dojo/explorer/Dockerfile @@ -0,0 +1,33 @@ +FROM node:8.12.0-stretch + +ENV LOGS_DIR /data/logs +ENV APP_DIR /home/node/app + +ENV EXPLORER_URL https://github.com/janoside/btc-rpc-explorer/archive +ENV EXPLORER_VERSION 1.1.5 + + +# Create logs and apps directory +RUN mkdir -p "$LOGS_DIR" && \ + chown -R node:node "$LOGS_DIR" && \ + mkdir "$APP_DIR" + +# Download the source code and install it +RUN set -ex && \ + wget -qO explorer.tar.gz "$EXPLORER_URL/v$EXPLORER_VERSION.tar.gz" && \ + tar -xzvf explorer.tar.gz -C "$APP_DIR/" --strip-components 1 && \ + rm explorer.tar.gz && \ + cd "$APP_DIR" && \ + npm install --only=prod && \ + chown -R node:node "$APP_DIR" + +# Copy restart script +COPY ./restart.sh "$APP_DIR/restart.sh" + +RUN chown node:node "$APP_DIR/restart.sh" && \ + chmod u+x "$APP_DIR/restart.sh" && \ + chmod g+x "$APP_DIR/restart.sh" + +EXPOSE 3002 + +USER node \ No newline at end of file diff --git a/docker/my-dojo/explorer/restart.sh b/docker/my-dojo/explorer/restart.sh new file mode 100644 index 0000000..4da82fa --- /dev/null +++ b/docker/my-dojo/explorer/restart.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +cd /home/node/app + +explorer_options=( + --port 3002 + --host 172.28.1.7 + --basic-auth-password "$EXPLORER_KEY" + --coin BTC + --bitcoind-host "$BITCOIND_IP" + --bitcoind-port "$BITCOIND_RPC_PORT" + --bitcoind-user "$BITCOIND_RPC_USER" + --bitcoind-pass "$BITCOIND_RPC_PASSWORD" + --no-rates + --privacy-mode +) + +# Blacklist all functions provided by the RPC API +explorer_options+=(--rpc-blacklist "addnode,analyzepsbt,clearbanned,combinepsbt,combinerawtransaction,converttopsbt,createmultisig,createpsbt,createrawtransaction,decodepsbt,decoderawtransaction,decodescript,deriveaddresses,disconnectnode,echo,echojson,estimaterawfee,estimatesmartfee,finalizepsbt,generatetoaddress,generatetodescriptor,getaddednodeinfo,getbestblockhash,getblock,getblockchaininfo,getblockcount,getblockfilter,getblockhash,getblockheader,getblockstats,getblocktemplate,getchaintips,getchaintxstats,getconnectioncount,getdescriptorinfo,getdifficulty,getmemoryinfo,getmempoolancestors,getmempooldescendants,getmempoolentry,getmempoolinfo,getmininginfo,getnettotals,getnetworkhashps,getnetworkinfo,getnodeaddresses,getpeerinfo,getrawmempool,getrawtransaction,getrpcinfo,gettxout,gettxoutproof,gettxoutsetinfo,help,invalidateblock,joinpsbts,listbanned,logging,ping,preciousblock,prioritisetransaction,pruneblockchain,reconsiderblock,savemempool,scantxoutset,sendrawtransaction,setban,setmocktime,setnetworkactive,signmessagewithprivkey,signrawtransactionwithkey,stop,submitblock,submitheader,syncwithvalidationinterfacequeue,testmempoolaccept,uptime,utxoupdatepsbt,validateaddress,verifychain,verifymessage,verifytxoutproof,waitforblock,waitforblockheight,waitfornewblock") + +node ./bin/cli.js "${explorer_options[@]}" > /data/logs/explorer-error.log 2> /data/logs/explorer-output.log diff --git a/docker/my-dojo/install/install-scripts.sh b/docker/my-dojo/install/install-scripts.sh index 88b6bcd..79b2142 100755 --- a/docker/my-dojo/install/install-scripts.sh +++ b/docker/my-dojo/install/install-scripts.sh @@ -6,6 +6,12 @@ else source ./conf/docker-bitcoind.conf.tpl fi +if [ -f ./conf/docker-explorer.conf ]; then + source ./conf/docker-explorer.conf +else + source ./conf/docker-explorer.conf.tpl +fi + if [ -f ./conf/docker-common.conf ]; then source ./conf/docker-common.conf else @@ -49,10 +55,20 @@ init_config_files() { cp ./conf/docker-node.conf.tpl ./conf/docker-node.conf echo "Initialized docker-node.conf" + cp ./conf/docker-explorer.conf.tpl ./conf/docker-explorer.conf + echo "Initialized docker-explorer.conf" + cp ./conf/docker-tor.conf.tpl ./conf/docker-tor.conf echo "Initialized docker-tor.conf" - # Initialize config files for nginx and the maintenance tool + # Initialize config files for nginx and the maintenance tool + if [ "$EXPLORER_INSTALL" == "on" ]; then + cp ./nginx/explorer.conf ./nginx/dojo-explorer.conf + else + cp /dev/null ./nginx/dojo-explorer.conf + fi + echo "Initialized dojo-explorer.conf (nginx)" + if [ "$COMMON_BTC_NETWORK" == "testnet" ]; then cp ./nginx/testnet.conf ./nginx/dojo.conf echo "Initialized dojo.conf (nginx)" diff --git a/docker/my-dojo/install/upgrade-scripts.sh b/docker/my-dojo/install/upgrade-scripts.sh index 9c4f44f..68554aa 100755 --- a/docker/my-dojo/install/upgrade-scripts.sh +++ b/docker/my-dojo/install/upgrade-scripts.sh @@ -6,6 +6,12 @@ else source ./conf/docker-common.conf.tpl fi +if [ -f ./conf/docker-explorer.conf ]; then + source ./conf/docker-explorer.conf +else + source ./conf/docker-explorer.conf.tpl +fi + source ./conf/docker-bitcoind.conf # Confirm upgrade operation @@ -45,10 +51,20 @@ update_config_files() { update_config_file ./conf/docker-node.conf ./conf/docker-node.conf.tpl echo "Initialized docker-node.conf" + update_config_file ./conf/docker-explorer.conf ./conf/docker-explorer.conf.tpl + echo "Initialized docker-explorer.conf" + update_config_file ./conf/docker-tor.conf ./conf/docker-tor.conf.tpl echo "Initialized docker-tor.conf" # Initialize config files for nginx and the maintenance tool + if [ "$EXPLORER_INSTALL" == "on" ]; then + cp ./nginx/explorer.conf ./nginx/dojo-explorer.conf + else + cp /dev/null ./nginx/dojo-explorer.conf + fi + echo "Initialized dojo-explorer.conf (nginx)" + if [ "$COMMON_BTC_NETWORK" == "testnet" ]; then cp ./nginx/testnet.conf ./nginx/dojo.conf echo "Initialized dojo.conf (nginx)" diff --git a/docker/my-dojo/nginx/Dockerfile b/docker/my-dojo/nginx/Dockerfile index 4eef0b5..93db47a 100644 --- a/docker/my-dojo/nginx/Dockerfile +++ b/docker/my-dojo/nginx/Dockerfile @@ -1,18 +1,18 @@ -FROM nginx:1.15.10-alpine +FROM nginx:1.15.10-alpine # Create data directory -ENV LOGS_DIR /data/logs +ENV LOGS_DIR /data/logs -RUN mkdir -p "$LOGS_DIR" && \ - chown -R nginx:nginx "$LOGS_DIR" +RUN mkdir -p "$LOGS_DIR" && \ + chown -R nginx:nginx "$LOGS_DIR" # Copy configuration files -COPY ./nginx.conf /etc/nginx/nginx.conf - -COPY ./dojo.conf /etc/nginx/sites-enabled/dojo.conf +COPY ./nginx.conf /etc/nginx/nginx.conf +COPY ./dojo.conf /etc/nginx/sites-enabled/dojo.conf +COPY ./dojo-explorer.conf /etc/nginx/sites-enabled/dojo-explorer.conf # Copy wait-for script -COPY ./wait-for /wait-for +COPY ./wait-for /wait-for -RUN chmod u+x /wait-for && \ - chmod g+x /wait-for \ No newline at end of file +RUN chmod u+x /wait-for && \ + chmod g+x /wait-for \ No newline at end of file diff --git a/docker/my-dojo/nginx/explorer.conf b/docker/my-dojo/nginx/explorer.conf new file mode 100644 index 0000000..f1fa695 --- /dev/null +++ b/docker/my-dojo/nginx/explorer.conf @@ -0,0 +1,15 @@ +server { + listen 9080; + server_name _; + resolver 127.0.0.11 valid=30s; + + location / { + set $upstream http://explorer:3002; + proxy_pass $upstream; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } +} diff --git a/docker/my-dojo/node/Dockerfile b/docker/my-dojo/node/Dockerfile index eb5fbcb..418d6fa 100644 --- a/docker/my-dojo/node/Dockerfile +++ b/docker/my-dojo/node/Dockerfile @@ -4,6 +4,10 @@ ENV LOGS_DIR /data/logs ENV APP_DIR /home/node/app +# Add node user to tor group +RUN addgroup --system -gid 1107 tor && \ + usermod -a -G tor node + # Install forever RUN npm install -g forever diff --git a/docker/my-dojo/overrides/explorer.install.yaml b/docker/my-dojo/overrides/explorer.install.yaml new file mode 100644 index 0000000..5c3d3d1 --- /dev/null +++ b/docker/my-dojo/overrides/explorer.install.yaml @@ -0,0 +1,28 @@ +version: "3.2" + +services: + explorer: + image: "samouraiwallet/dojo-explorer:${DOJO_EXPLORER_VERSION_TAG}" + container_name: explorer + build: + context: ./explorer + env_file: + - ./.env + - ./conf/docker-bitcoind.conf + - ./conf/docker-explorer.conf + restart: on-failure + command: "/home/node/app/restart.sh" + expose: + - "3002" + volumes: + - data-explorer:/data/logs + networks: + dojonet: + ipv4_address: 172.28.1.7 + + node: + depends_on: + - explorer + +volumes: + data-explorer: diff --git a/docker/my-dojo/tor/restart.sh b/docker/my-dojo/tor/restart.sh index c3b29bb..e99aa1e 100644 --- a/docker/my-dojo/tor/restart.sh +++ b/docker/my-dojo/tor/restart.sh @@ -25,6 +25,13 @@ tor_options=( --HiddenServiceDirGroupReadable 1 ) +if [ "$EXPLORER_INSTALL" == "on" ]; then + tor_options+=(--HiddenServiceDir /var/lib/tor/hsv3explorer) + tor_options+=(--HiddenServiceVersion 3) + tor_options+=(--HiddenServicePort "80 172.29.1.3:9080") + tor_options+=(--HiddenServiceDirGroupReadable 1) +fi + if [ "$TOR_USE_BRIDGES" == "on" ]; then tor_options+=(--ClientTransportPlugin "obfs4 exec /usr/local/bin/obfs4proxy") tor_options+=(--UseBridges 1) diff --git a/static/admin/css/style.css b/static/admin/css/style.css index 3aa4ea0..8717b2e 100644 --- a/static/admin/css/style.css +++ b/static/admin/css/style.css @@ -370,11 +370,20 @@ table.spaced tr td { } /* PAIRING */ -#qr-label { +#qr-label, +#qr-explorer-label { margin: 0 0 20px 0; + text-align: center; + display: inline-block; +} + +#qr-container, +#qr-explorer-container { + display: inline-block; } -#qr-pairing { +#qr-pairing, +#qr-explorer-pairing { width: 276px; height: 276px; padding: 10px; @@ -390,8 +399,8 @@ table.spaced tr td { } .halfwidth { - width: 50%; - min-width: 50%; + width: 49%; + min-width: 49%; } .fullwidth { diff --git a/static/admin/lib/api-wrapper.js b/static/admin/lib/api-wrapper.js index 8327724..90ee2f9 100644 --- a/static/admin/lib/api-wrapper.js +++ b/static/admin/lib/api-wrapper.js @@ -39,6 +39,15 @@ var lib_api = { return this.sendGetUriEncoded(uri, {}); }, + /** + * Get block explorer pairing info + */ + getExplorerPairingInfo: function() { + let prefix = conf['prefixes']['support']; + let uri = this.baseUri + '/' + prefix + '/pairing/explorer'; + return this.sendGetUriEncoded(uri, {}); + }, + /** * PushTx Status */ diff --git a/static/admin/tool/index.html b/static/admin/tool/index.html index 350439b..db72299 100644 --- a/static/admin/tool/index.html +++ b/static/admin/tool/index.html @@ -86,10 +86,22 @@
-
- PAIR YOUR SAMOURAI WALLET WITH YOUR DOJO BY SCANNING THIS QRCODE +
+
+ PAIR YOUR WALLET WITH YOUR DOJO +
+
+ PAIR YOUR WALLET WITH YOUR BLOCK EXPLORER +
+
+
+
+
+
+
+
+
-
diff --git a/static/admin/tool/index.js b/static/admin/tool/index.js index 66f445f..d2b174c 100644 --- a/static/admin/tool/index.js +++ b/static/admin/tool/index.js @@ -16,12 +16,25 @@ function displayQRPairing() { const activeTab = sessionStorage.getItem('activeTab'); processAction(activeTab).then( function (result) { - if (!result) {return;} - const url = window.location.protocol + '//' + window.location.host + conf['api']['baseUri']; - result['pairing']['url'] = url; - const textJson = JSON.stringify(result, null, 4); - $("#qr-pairing").html('') // clear qrcode first - $('#qr-pairing').qrcode({width: 256, height: 256, text: textJson}); + if (result) { + if (result['api']) { + const textJson = JSON.stringify(result['api'], null, 4); + $("#qr-pairing").html('') // clear qrcode first + $('#qr-pairing').qrcode({width: 256, height: 256, text: textJson}); + } + if (result['explorer'] && result['explorer']['pairing']['url']) { + const textJson = JSON.stringify(result['explorer'], null, 4); + $("#qr-explorer-pairing").html('') // clear qrcode first + $('#qr-explorer-pairing').qrcode({width: 256, height: 256, text: textJson}); + } else { + $("#qr-label").removeClass('halfwidth'); + $("#qr-label").addClass('fullwidth'); + $("#qr-container").removeClass('halfwidth'); + $("#qr-container").addClass('fullwidth'); + $("#qr-explorer-label").hide(); + $("#qr-explorer-container").hide(); + } + } }, function (jqxhr) {} ); @@ -147,14 +160,34 @@ function preparePage() { * Process action (api calls) */ function processAction(activeTab, args, args2, args3) { - if (activeTab == '#link-pairing') - return lib_api.getPairingInfo(); - else if (activeTab == '#link-status-api') + if (activeTab == '#link-pairing') { + //return lib_api.getPairingInfo(); + let result = { + 'api': null, + 'explorer': null + }; + return lib_api.getPairingInfo().then(apiInfo => { + if (apiInfo) { + apiInfo['pairing']['url'] = window.location.protocol + '//' + window.location.host + conf['api']['baseUri']; + result['api'] = apiInfo; + } + }).then(() => { + return lib_api.getExplorerPairingInfo(); + }).then(explorerInfo => { + if (explorerInfo) + result['explorer'] = explorerInfo; + return result + }).catch(e => { + console.log(e); + return result; + }); + } else if (activeTab == '#link-status-api') { return lib_api.getApiStatus(); - else if (activeTab == '#link-status-pushtx') + } else if (activeTab == '#link-status-pushtx') { return lib_api.getPushtxStatus(); - else if (activeTab == '#link-orchestrator') + } else if (activeTab == '#link-orchestrator') { return lib_api.getOrchestratorStatus(); + } if (args == '') { alert('Argument is mandatory');