From 723253ef6f8a3ccd4e427e39d18c319118d3a07e Mon Sep 17 00:00:00 2001 From: SKP Date: Sun, 17 Nov 2019 16:20:17 +0100 Subject: [PATCH 1/9] Using cam tool to manager apps and app keys --- cyphernodeconf_docker/lib/app.js | 1 + .../prompters/999_installer.js | 4 ++-- .../templates/installer/cam.sh | 6 +++++ .../templates/installer/start.sh | 21 +++++----------- .../templates/installer/stop.sh | 24 ++++++------------- dist/setup.sh | 21 ++++++++++++---- 6 files changed, 39 insertions(+), 38 deletions(-) create mode 100644 cyphernodeconf_docker/templates/installer/cam.sh diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index e9cb672f6..e90e432a3 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -88,6 +88,7 @@ module.exports = class App { lightning_version: process.env.LIGHTNING_VERSION, notifier_version: process.env.NOTIFIER_VERSION, setup_version: process.env.SETUP_VERSION, + cam_version: process.env.CAM_VERSION || 'latest', noWizard: !!options.noWizard, noSplashScreen: !!options.noSplashScreen, lightning_nodename: name.generate(), diff --git a/cyphernodeconf_docker/prompters/999_installer.js b/cyphernodeconf_docker/prompters/999_installer.js index 1d3ca184a..808124ac5 100644 --- a/cyphernodeconf_docker/prompters/999_installer.js +++ b/cyphernodeconf_docker/prompters/999_installer.js @@ -302,8 +302,8 @@ module.exports = { }, templates: function( props ) { if( props.installer_mode === 'docker' ) { - return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', path.join('docker', 'docker-compose.yaml')]; + return ['config.sh','start.sh', 'stop.sh', 'cam.sh', 'testfeatures.sh', 'testdeployment.sh', path.join('docker', 'docker-compose.yaml')]; } - return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh']; + return ['config.sh','start.sh', 'stop.sh', 'cam.sh', 'testfeatures.sh', 'testdeployment.sh']; } }; diff --git a/cyphernodeconf_docker/templates/installer/cam.sh b/cyphernodeconf_docker/templates/installer/cam.sh new file mode 100644 index 000000000..6ebf2a6dc --- /dev/null +++ b/cyphernodeconf_docker/templates/installer/cam.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" +# !!!!!!!!! DO NOT INCLUDE APPS WITHOUT REVIEW !!!!!!!!!! + +docker run -e CYPHERAPPS_INSTALL_DIR=/apps -v "$current_path"/apps:/apps -v "$current_path":/data --rm cyphernode/cam:<%= cam_version %> $* diff --git a/cyphernodeconf_docker/templates/installer/start.sh b/cyphernodeconf_docker/templates/installer/start.sh index dbc0b7408..43c7a03cd 100644 --- a/cyphernodeconf_docker/templates/installer/start.sh +++ b/cyphernodeconf_docker/templates/installer/start.sh @@ -2,11 +2,8 @@ . ./.cyphernodeconf/installer/config.sh -# be aware that randomly downloaded cyphernode apps will have access to -# your configuration and filesystem. +current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" # !!!!!!!!! DO NOT INCLUDE APPS WITHOUT REVIEW !!!!!!!!!! -# TODO: Test if we can mitigate this security issue by -# running app dockers inside a docker container start_apps() { local SCRIPT_NAME="start.sh" @@ -17,20 +14,14 @@ start_apps() { for i in $current_path/apps/* do APP_SCRIPT_PATH=$(echo $i) - if [ -d "$APP_SCRIPT_PATH" ] && [ ! -f "$APP_SCRIPT_PATH/ignoreThisApp" ]; then + if [ -d "$APP_SCRIPT_PATH" ]; then APP_START_SCRIPT_PATH="$APP_SCRIPT_PATH/$SCRIPT_NAME" APP_ID=$(basename $APP_SCRIPT_PATH) - if [ -f "$APP_START_SCRIPT_PATH" ]; then - . $APP_START_SCRIPT_PATH - elif [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then - export SHARED_HTPASSWD_PATH - export GATEKEEPER_DATAPATH - export GATEKEEPER_PORT - export LIGHTNING_DATAPATH - export BITCOIN_DATAPATH - export APP_SCRIPT_PATH - export APP_ID + if [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then + export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/cert.pem" + export CLIGHTNING_RPC_SOCKET="$LIGHTNING_DATAPATH/lightning-rpc" + export APP_DATA="$APP_SCRIPT_PATH" export DOCKER_MODE if [ "$DOCKER_MODE" = "swarm" ]; then diff --git a/cyphernodeconf_docker/templates/installer/stop.sh b/cyphernodeconf_docker/templates/installer/stop.sh index 4e6649c49..895f7dbc0 100644 --- a/cyphernodeconf_docker/templates/installer/stop.sh +++ b/cyphernodeconf_docker/templates/installer/stop.sh @@ -1,13 +1,9 @@ #!/bin/sh -current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" - +. ./.cyphernodeconf/installer/config.sh -# be aware that randomly downloaded cyphernode apps will have access to -# your configuration and filesystem. +current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" # !!!!!!!!! DO NOT INCLUDE APPS WITHOUT REVIEW !!!!!!!!!! -# TODO: Test if we can mitigate this security issue by -# running app dockers inside a docker container stop_apps() { local SCRIPT_NAME="stop.sh" @@ -18,20 +14,14 @@ stop_apps() { for i in $current_path/apps/* do APP_SCRIPT_PATH=$(echo $i) - if [ -d "$APP_SCRIPT_PATH" ] && [ ! -f "$APP_SCRIPT_PATH/ignoreThisApp" ]; then + if [ -d "$APP_SCRIPT_PATH" ]; then APP_STOP_SCRIPT_PATH="$APP_SCRIPT_PATH/$SCRIPT_NAME" APP_ID=$(basename $APP_SCRIPT_PATH) - if [ -f "$APP_STOP_SCRIPT_PATH" ]; then - . $APP_STOP_SCRIPT_PATH - elif [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then - export SHARED_HTPASSWD_PATH - export GATEKEEPER_DATAPATH - export GATEKEEPER_PORT - export LIGHTNING_DATAPATH - export BITCOIN_DATAPATH - export APP_SCRIPT_PATH - export APP_ID + if [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then + export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/cert.pem" + export CLIGHTNING_RPC_SOCKET="$LIGHTNING_DATAPATH/lightning-rpc" + export APP_DATA="$APP_SCRIPT_PATH" export DOCKER_MODE if [ "$DOCKER_MODE" = "swarm" ]; then diff --git a/dist/setup.sh b/dist/setup.sh index 0d585933c..34dee03f3 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -193,6 +193,7 @@ configure() { -e BITCOIN_VERSION=$BITCOIN_VERSION \ -e LIGHTNING_VERSION=$LIGHTNING_VERSION \ -e SETUP_VERSION=$SETUP_VERSION \ + -e CAM_VERSION=$CAM_VERSION \ --log-driver=none$pw_env \ --network none \ --rm$interactive cyphernode/cyphernodeconf:$CONF_VERSION $user node index.js$recreate @@ -538,6 +539,7 @@ install_docker() { copy_file $cyphernodeconf_filepath/installer/testfeatures.sh $current_path/testfeatures.sh 0 copy_file $cyphernodeconf_filepath/installer/start.sh $current_path/start.sh 0 copy_file $cyphernodeconf_filepath/installer/stop.sh $current_path/stop.sh 0 + copy_file $cyphernodeconf_filepath/installer/cam.sh $current_path/cam.sh 0 copy_file $cyphernodeconf_filepath/installer/testdeployment.sh $current_path/testdeployment.sh 0 if [[ ! -x $current_path/start.sh ]]; then @@ -552,6 +554,12 @@ install_docker() { next fi + if [[ ! -x $current_path/cam.sh ]]; then + step " make cam.sh executable" + try chmod +x $current_path/cam.sh + next + fi + if [[ ! -x $current_path/testfeatures.sh ]]; then step " make testfeatures.sh executable" try chmod +x $current_path/testfeatures.sh @@ -692,10 +700,14 @@ sanity_checks_pre_install() { install_apps() { if [ ! -d "$current_path/apps" ]; then - local apps_repo="https://github.com/SatoshiPortal/cypherapps.git" - echo " clone $apps_repo into apps" - docker run --rm -v "$current_path":/git --entrypoint git cyphernode/cyphernodeconf:$CONF_VERSION clone --single-branch -b ${CYPHERAPPS_VERSION} "$apps_repo" /git/apps > /dev/null 2>&1 - fi + sudo_if_required mkdir -p "$current_path/apps" + fi + ./cam.sh i + copy_file "$cyphernodeconf_filepath/gatekeeper/keys.properties" "$current_path/.cam/keys.properties" 1 $SUDO_REQUIRED + ./cam.sh u + ./cam.sh a i G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo + ./cam.sh a i YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo + ./cam.sh a k a G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key } install() { @@ -726,6 +738,7 @@ PYCOIN_VERSION="v0.2.4" CYPHERAPPS_VERSION="v0.2.2" BITCOIN_VERSION="v0.18.0" LIGHTNING_VERSION="v0.7.1" +CAM_VERSION="v0.1.0" SETUP_DIR=$(dirname $(realpath $0)) From 74cfd1b5f002b88ab35cb1f2339e093059373e5f Mon Sep 17 00:00:00 2001 From: SKP Date: Sun, 17 Nov 2019 16:27:31 +0100 Subject: [PATCH 2/9] Renamed install_apps to install_default_apps --- dist/setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/setup.sh b/dist/setup.sh index 34dee03f3..48e636583 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -698,7 +698,7 @@ sanity_checks_pre_install() { fi } -install_apps() { +install_default_apps() { if [ ! -d "$current_path/apps" ]; then sudo_if_required mkdir -p "$current_path/apps" fi @@ -706,8 +706,8 @@ install_apps() { copy_file "$cyphernodeconf_filepath/gatekeeper/keys.properties" "$current_path/.cam/keys.properties" 1 $SUDO_REQUIRED ./cam.sh u ./cam.sh a i G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo - ./cam.sh a i YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo ./cam.sh a k a G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key + ./cam.sh a i YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo } install() { @@ -826,7 +826,7 @@ if [[ $INSTALL == 1 ]]; then install modify_owner modify_permissions - install_apps + install_default_apps if [[ ! $AUTOSTART == 1 ]]; then cowsay fi From 5fdccf13ee0aba3776212c0148db02377fa0b307 Mon Sep 17 00:00:00 2001 From: SKP Date: Mon, 18 Nov 2019 10:51:39 +0100 Subject: [PATCH 3/9] Make usage of cam tool less cryptic by using full commands --- dist/setup.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/setup.sh b/dist/setup.sh index 48e636583..e8e65a37d 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -702,12 +702,12 @@ install_default_apps() { if [ ! -d "$current_path/apps" ]; then sudo_if_required mkdir -p "$current_path/apps" fi - ./cam.sh i + ./cam.sh init copy_file "$cyphernodeconf_filepath/gatekeeper/keys.properties" "$current_path/.cam/keys.properties" 1 $SUDO_REQUIRED - ./cam.sh u - ./cam.sh a i G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo - ./cam.sh a k a G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key - ./cam.sh a i YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo + ./cam.sh update + ./cam.sh app install G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo + ./cam.sh app kay add G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key + ./cam.sh app install YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo } install() { From b178e89dca7ad879e2c1a8e44273309b2984124f Mon Sep 17 00:00:00 2001 From: SKP Date: Mon, 18 Nov 2019 10:55:05 +0100 Subject: [PATCH 4/9] Fixed typo --- dist/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/setup.sh b/dist/setup.sh index e8e65a37d..22b93a3ea 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -706,7 +706,7 @@ install_default_apps() { copy_file "$cyphernodeconf_filepath/gatekeeper/keys.properties" "$current_path/.cam/keys.properties" 1 $SUDO_REQUIRED ./cam.sh update ./cam.sh app install G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo - ./cam.sh app kay add G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key + ./cam.sh app key add G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key ./cam.sh app install YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo } From 82bbd720ec287ecfbd510df5c4a4ed6163b163a3 Mon Sep 17 00:00:00 2001 From: SKP Date: Mon, 18 Nov 2019 10:57:22 +0100 Subject: [PATCH 5/9] Copy installation info to .cam directory for the compatibility check --- dist/setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/setup.sh b/dist/setup.sh index 22b93a3ea..9a2867799 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -704,6 +704,7 @@ install_default_apps() { fi ./cam.sh init copy_file "$cyphernodeconf_filepath/gatekeeper/keys.properties" "$current_path/.cam/keys.properties" 1 $SUDO_REQUIRED + copy_file "$cyphernodeconf_filepath/cyphernode/info.json" "$current_path/.cam/cyphernode.json" 1 $SUDO_REQUIRED ./cam.sh update ./cam.sh app install G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo ./cam.sh app key add G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key From 82081e5c5dd12b0b6848520027cc72249d5d690f Mon Sep 17 00:00:00 2001 From: SKP Date: Fri, 22 Nov 2019 12:24:22 +0100 Subject: [PATCH 6/9] Added container names to docker-compose --- .../templates/installer/docker/docker-compose.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index 7971a8762..26c7771ef 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -8,6 +8,7 @@ services: ########################## bitcoin: + container_name: bitcoin image: cyphernode/bitcoin:<%= bitcoin_version %> command: $USER bitcoind <% if( bitcoin_expose ) { %> @@ -36,6 +37,7 @@ services: ########################## proxy: + container_name: proxy image: cyphernode/proxy:<%= proxy_version %> command: $USER ./startproxy.sh environment: @@ -85,6 +87,7 @@ services: ########################## proxycron: + container_name: proxycron image: cyphernode/proxycron:<%= proxycron_version %> environment: - "TX_CONF_URL=proxy:8888/executecallbacks" @@ -103,6 +106,7 @@ services: ########################## broker: + container_name: broker image: eclipse-mosquitto:1.6 networks: - cyphernodenet @@ -116,6 +120,7 @@ services: ########################## notifier: + container_name: notifier image: cyphernode/notifier:<%= notifier_version %> command: $USER ./startnotifier.sh networks: @@ -133,6 +138,7 @@ services: ########################## pycoin: + container_name: pycoin image: cyphernode/pycoin:<%= pycoin_version %> command: $USER ./startpycoin.sh environment: @@ -155,6 +161,7 @@ services: ########################## otsclient: + container_name: otsclient image: cyphernode/otsclient:<%= otsclient_version %> command: $USER /script/startotsclient.sh environment: @@ -181,6 +188,7 @@ services: gatekeeper: # HTTP authentication API gate + container_name: gatekeeper image: cyphernode/gatekeeper:<%= gatekeeper_version %> command: $USER environment: @@ -214,6 +222,7 @@ services: ########################## traefik: + container_name: traefik image: traefik:v1.7.9-alpine ports: - 80:80 @@ -238,6 +247,7 @@ services: ########################## lightning: + container_name: lightning image: cyphernode/clightning:<%= lightning_version %> command: $USER sh -c 'while [ ! -f "/bitcoin_monitor/up" ]; do echo "bitcoin not ready" ; sleep 10 ; done ; echo "bitcoin ready!" ; lightningd' <% if( lightning_expose ) { %> From fde5d3541bc8af783638654fcfcdeeb863dae69c Mon Sep 17 00:00:00 2001 From: SKP Date: Fri, 22 Nov 2019 13:39:02 +0100 Subject: [PATCH 7/9] Fixed cert paths --- cyphernodeconf_docker/templates/installer/start.sh | 2 +- cyphernodeconf_docker/templates/installer/stop.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cyphernodeconf_docker/templates/installer/start.sh b/cyphernodeconf_docker/templates/installer/start.sh index 43c7a03cd..ecd0abaae 100644 --- a/cyphernodeconf_docker/templates/installer/start.sh +++ b/cyphernodeconf_docker/templates/installer/start.sh @@ -19,7 +19,7 @@ start_apps() { APP_ID=$(basename $APP_SCRIPT_PATH) if [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then - export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/cert.pem" + export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/certs/cert.pem" export CLIGHTNING_RPC_SOCKET="$LIGHTNING_DATAPATH/lightning-rpc" export APP_DATA="$APP_SCRIPT_PATH" export DOCKER_MODE diff --git a/cyphernodeconf_docker/templates/installer/stop.sh b/cyphernodeconf_docker/templates/installer/stop.sh index 895f7dbc0..78bbffbe4 100644 --- a/cyphernodeconf_docker/templates/installer/stop.sh +++ b/cyphernodeconf_docker/templates/installer/stop.sh @@ -19,7 +19,7 @@ stop_apps() { APP_ID=$(basename $APP_SCRIPT_PATH) if [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then - export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/cert.pem" + export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/certs/cert.pem" export CLIGHTNING_RPC_SOCKET="$LIGHTNING_DATAPATH/lightning-rpc" export APP_DATA="$APP_SCRIPT_PATH" export DOCKER_MODE From 6a49d3ac95762dde2bbdf1fe8cdc765a504901fa Mon Sep 17 00:00:00 2001 From: SKP Date: Sat, 23 Nov 2019 14:10:29 +0100 Subject: [PATCH 8/9] Setting correct environment for apps --- cyphernodeconf_docker/templates/installer/start.sh | 5 +++-- cyphernodeconf_docker/templates/installer/stop.sh | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cyphernodeconf_docker/templates/installer/start.sh b/cyphernodeconf_docker/templates/installer/start.sh index ecd0abaae..cabe8bd57 100644 --- a/cyphernodeconf_docker/templates/installer/start.sh +++ b/cyphernodeconf_docker/templates/installer/start.sh @@ -19,10 +19,11 @@ start_apps() { APP_ID=$(basename $APP_SCRIPT_PATH) if [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then - export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/certs/cert.pem" - export CLIGHTNING_RPC_SOCKET="$LIGHTNING_DATAPATH/lightning-rpc" + export GATEKEEPER_CERTS_PATH="$GATEKEEPER_DATAPATH/certs" + export UNSAFE__CLIGHTNING_PATH="$LIGHTNING_DATAPATH" export APP_DATA="$APP_SCRIPT_PATH" export DOCKER_MODE + export GATEKEEPER_URL="https://gatekeeper:${GATEKEEPER_PORT}" if [ "$DOCKER_MODE" = "swarm" ]; then docker stack deploy -c $APP_SCRIPT_PATH/docker-compose.yaml $APP_ID diff --git a/cyphernodeconf_docker/templates/installer/stop.sh b/cyphernodeconf_docker/templates/installer/stop.sh index 78bbffbe4..5f9407d1c 100644 --- a/cyphernodeconf_docker/templates/installer/stop.sh +++ b/cyphernodeconf_docker/templates/installer/stop.sh @@ -19,10 +19,11 @@ stop_apps() { APP_ID=$(basename $APP_SCRIPT_PATH) if [ -f "$APP_SCRIPT_PATH/docker-compose.yaml" ]; then - export GATEKEEPER_CERT_FILE="$GATEKEEPER_DATAPATH/certs/cert.pem" - export CLIGHTNING_RPC_SOCKET="$LIGHTNING_DATAPATH/lightning-rpc" + export GATEKEEPER_CERTS_PATH="$GATEKEEPER_DATAPATH/certs" + export UNSAFE__CLIGHTNING_PATH="$LIGHTNING_DATAPATH" export APP_DATA="$APP_SCRIPT_PATH" export DOCKER_MODE + export GATEKEEPER_URL="https://gatekeeper:${GATEKEEPER_PORT}" if [ "$DOCKER_MODE" = "swarm" ]; then docker stack rm $APP_ID From 1c6382e1c0acb6532e08bcb7688b2c9060f04886 Mon Sep 17 00:00:00 2001 From: SKP Date: Sat, 23 Nov 2019 14:26:49 +0100 Subject: [PATCH 9/9] Added fixed version to app installation --- dist/setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/setup.sh b/dist/setup.sh index 9a2867799..4f5c65313 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -706,9 +706,9 @@ install_default_apps() { copy_file "$cyphernodeconf_filepath/gatekeeper/keys.properties" "$current_path/.cam/keys.properties" 1 $SUDO_REQUIRED copy_file "$cyphernodeconf_filepath/cyphernode/info.json" "$current_path/.cam/cyphernode.json" 1 $SUDO_REQUIRED ./cam.sh update - ./cam.sh app install G-bToO5cvzSg1dZbYSINSYs93ao #welcome from official repo + ./cam.sh app install G-bToO5cvzSg1dZbYSINSYs93ao@$CYPHERAPPS_VERSION #welcome from official repo ./cam.sh app key add G-bToO5cvzSg1dZbYSINSYs93ao 000 #give welcome the stats key - ./cam.sh app install YFeXUM86dipa0ORC2iclAcMcSFU #sparkwallet from official repo + ./cam.sh app install YFeXUM86dipa0ORC2iclAcMcSFU@$CYPHERAPPS_VERSION #sparkwallet from official repo } install() {