Merge branch 'v1.6' into add-thunderhub

This commit is contained in:
openoms 2020-06-02 09:02:31 +01:00 committed by GitHub
commit 4b21528671
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1085 additions and 258 deletions

1
FAQ.md
View file

@ -2,6 +2,7 @@
## Whats new in Version 1.6 of RaspiBlitz?
- Update: Raspberry Pi OS Base Image (May 2020)
- Fix: DropBox StaticChannelBackup
- New: Balance of Satoshis [details](https://github.com/alexbosworth/balanceofsatoshis)
- New: Faraday [details](https://github.com/lightninglabs/faraday)

View file

@ -1,16 +1,16 @@
#!/bin/bash
#########################################################################
# Build your SD card image based on:
# Raspbian Buster Desktop (2020-02-13)
# Raspbian Buster Desktop (2020-05-27)
# https://www.raspberrypi.org/downloads/raspbian/
# SHA256: a82ed4139dfad31c3167e60e943bcbe28c404d1858f4713efe5530c08a419f50
# SHA256: b9a5c5321b3145e605b3bcd297ca9ffc350ecb1844880afd8fb75a7589b7bd04
##########################################################################
# setup fresh SD card with image above - login per SSH and run this script:
##########################################################################
echo ""
echo "*****************************************"
echo "* RASPIBLITZ SD CARD IMAGE SETUP v1.5 *"
echo "* RASPIBLITZ SD CARD IMAGE SETUP v1.6 *"
echo "*****************************************"
echo ""
@ -493,7 +493,7 @@ sudo -u admin wget -N https://github.com/lightningnetwork/lnd/releases/download/
# check if checksums are signed by lnd dev team
sudo -u admin wget -N https://github.com/lightningnetwork/lnd/releases/download/v${lndVersion}/manifest-v${lndVersion}.txt.sig
sudo -u admin wget -N -O "pgp_keys.asc" ${PGPpkeys}
sudo -u admin wget --no-check-certificate -N -O "pgp_keys.asc" ${PGPpkeys}
gpg ./pgp_keys.asc
fingerprint=$(sudo gpg "pgp_keys.asc" 2>/dev/null | grep "${PGPcheck}" -c)
if [ ${fingerprint} -lt 1 ]; then
@ -591,10 +591,10 @@ echo "*** Python DEFAULT libs & depenedencies ***"
# for setup schell scripts
sudo apt-get -y install dialog bc python3-dialog
# libs
# libs (for global python scripts)
sudo pip3 install -I grpcio==1.29.0
sudo pip3 install -I googleapis-common-protos==1.51.0
sudo pip3 install -I toml==0.10.1
echo ""
echo "*** RASPIBLITZ EXTRAS ***"

View file

@ -96,6 +96,7 @@ if [ "${chain}" = "main" ]; then
fi
OPTIONS+=(SERVICES "Activate/Deactivate Services")
OPTIONS+=(SUBSCRIBE "Manage Subscriptions")
OPTIONS+=(MOBILE "Connect Mobile Wallet")
OPTIONS+=(LNDCREDS "Manage LND Credentials")
OPTIONS+=(NAME "Change Name/Alias of Node")
@ -180,6 +181,9 @@ case $CHOICE in
THUB)
sudo /home/admin/config.scripts/bonus.thunderhub.sh menu
;;
SUBSCRIBE)
/home/admin/config.scripts/blitz.subscriptions.py
;;
lnbalance)
clear
echo "*** YOUR SATOSHI BALANCES ***"

View file

@ -206,7 +206,7 @@ How do you want to continue?
# check how many times LND was restarted
source <(sudo /home/admin/config.scripts/blitz.statusscan.sh)
if [ ${startcountLightning} -lt 4 ]; then
/home/admin/AAunlockLND.sh
/home/admin/config.scripts/lnd.unlock.sh
echo "Starting up Wallet ... (10sec)"
sleep 5
sleep 5

View file

@ -468,11 +468,8 @@ if [ "${autoUnlock}" != "${choice}" ]; then
l1="AUTO-UNLOCK IS NOW OFF"
if [ "${choice}" = "on" ]; then
l1="AUTO-UNLOCK IS NOW ACTIVE"
fi
l2="-------------------------"
l3="mobile/external wallets may need reconnect"
l4="possible change in macaroon / TLS cert"
dialog --title 'OK' --msgbox "${l1}\n${l2}\n${l3}\n${l4}" 11 60
fi
dialog --title 'OK' --msgbox "\n${l1}\n" 9 50
needsReboot=1
else
echo "LND Autounlock Setting unchanged."

View file

@ -55,16 +55,16 @@ if [ ${lndRunning} -eq 1 ]; then
# check if LND wallet exists and if locked
walletExists=$(sudo ls /mnt/hdd/lnd/data/chain/${network}/${chain}net/wallet.db 2>/dev/null | grep wallet.db -c)
locked=0
walletLocked=0
# only when a wallet exists - it can be locked
if [ ${walletExists} -eq 1 ];then
echo "lnd wallet exists ... checking if locked"
sleep 2
locked=$(sudo tail -n 1 /mnt/hdd/lnd/logs/${network}/${chain}net/lnd.log 2>/dev/null | grep -c unlock)
walletLocked=$(sudo -u bitcoin /usr/local/bin/lncli getinfo 2>&1 | grep -c unlock)
fi
if [ ${locked} -gt 0 ]; then
if [ ${walletLocked} -gt 0 ]; then
# LND wallet is locked
/home/admin/AAunlockLND.sh
/home/admin/config.scripts/lnd.unlock.sh
/home/admin/10setupBlitz.sh
exit 0
fi

View file

@ -446,7 +446,7 @@ echo "*** Copy LND Macaroons to user admin ***"
# check if macaroon exists and if not try to unlock LND wallet first
macaroonExists=$(sudo -u bitcoin ls -la /home/bitcoin/.lnd/data/chain/${network}/${chain}net/admin.macaroon 2>/dev/null | grep -c admin.macaroon)
if [ ${macaroonExists} -eq 0 ]; then
/home/admin/AAunlockLND.sh
/home/admin/config.scripts/lnd.unlock.sh
sleep 3
fi
@ -472,7 +472,7 @@ echo "*** Check Wallet Lock ***"
locked=$(sudo tail -n 1 /mnt/hdd/lnd/logs/${network}/${chain}net/lnd.log 2>/dev/null | grep -c unlock)
if [ ${locked} -gt 0 ]; then
echo "OK - Wallet is locked ... starting unlocking dialog"
/home/admin/AAunlockLND.sh
/home/admin/config.scripts/lnd.unlock.sh
else
echo "OK - Wallet is already unlocked"
fi

View file

@ -64,7 +64,7 @@ if [ ${bitcoinActive} -eq 0 ] || [ ${#bitcoinErrorFull} -gt 0 ] || [ "${1}" == "
fi
echo "-> Use following command to debug: /home/admin/XXdebugLogs.sh"
echo "-> To force Main Menu run: /home/admin/00mainMenu.sh"
echo "-> To try restart: sudo shutdown -r now"
echo "-> To try restart: restart"
echo ""
fi
else
@ -123,7 +123,7 @@ elif [ ${lndActive} -eq 0 ] || [ ${#lndErrorFull} -gt 0 ] || [ "${1}" == "lightn
echo
echo "-> Use following command to debug: /home/admin/XXdebugLogs.sh"
echo "-> To force Main Menu run: /home/admin/00mainMenu.sh"
echo "-> To try restart: sudo shutdown -r now"
echo "-> To try restart: restart"
echo ""
exit 1
else

View file

@ -5,25 +5,30 @@ source /home/admin/raspiblitz.info
source /mnt/hdd/raspiblitz.conf
justLocal=1
aks4IP2TOR=0
# if TOR is activated then outside reach is possible (no notice)
if [ "${runBehindTor}" = "on" ]; then
justLocal=0
aks4IP2TOR=1
fi
# if dynDomain is set connect from outside is possible (no notice)
if [ ${#dynDomain} -gt 0 ]; then
justLocal=0
aks4IP2TOR=0
fi
# if sshtunnel to 10009/8080 then outside reach is possible (no notice)
isForwarded=$(echo ${sshtunnel} | grep -c "10009<")
if [ ${isForwarded} -gt 0 ]; then
justLocal=0
aks4IP2TOR=0
fi
isForwarded=$(echo ${sshtunnel} | grep -c "8080<")
if [ ${isForwarded} -gt 0 ]; then
justLocal=0
fi
# if TOR is activated then outside reach is possible (no notice)
if [ "${runBehindTor}" = "on" ]; then
justLocal=0
aks4IP2TOR=0
fi
# check if dynamic domain is set
@ -67,6 +72,52 @@ choose_IP_or_TOR()
fi
}
# fuction to if already activated or user wants to activate IP2TOR
# needs parameter: #1 "LND-REST-API" or "LND-GRPC-API"
ip2tor=""
checkIP2TOR()
{
# check if IP2TOR service is already available
error=""
source <(/home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscription-by-service $1)
if [ ${#error} -eq 0 ]; then
ip2tor="$1"
fi
# if IP2TOR is not already available:
# and the checks from avove showed there is SSH forwarding / dynDNS
# then ask user if IP2TOR subscription is wanted
if [ ${#ip2tor} -eq 0 ] && [ ${aks4IP2TOR} -eq 1 ]; then
whiptail --title " Want to use a IP2TOR Bridge? " --yes-button "Go To Shop" --no-button "No Thanks" --yesno "It can be hard to configure your router or phone to connect to your RaspiBlitz at home.\n\nDo you like to subscribe to a IP2TOR bridge service (that will give you a public IP while hidden behind TOR) and make it more easy to connect your mobile wallet?" 12 60
if [ $? -eq 0 ]; then
echo "# yes-button -> Send To Shop"
port="10009"
toraddress=$(sudo cat /mnt/hdd/tor/lndrpc10009/hostname)
if [ "$1" == "LND-REST-API" ]; then
port="8080"
toraddress=$(sudo cat /mnt/hdd/tor/lndrest8080/hostname)
fi
userHasActiveChannels=$(sudo -u bitcoin lncli listchannels | grep -c '"active": true')
if [ ${userHasActiveChannels} -gt 0 ]; then
/home/admin/config.scripts/blitz.subscriptions.ip2tor.py create-ssh-dialog "$1" "$toraddress" "$port"
else
whiptail --title " Lightning not Ready " --msgbox "\nYou need at least one active Lightning channel.\n\nPlease make sure that your node is funded and\nyou have a confirmed and active channel running.\nThen try again to connect the mobile wallet." 13 52
exit 0
fi
clear
fi
fi
# check again if IP2TOR service is now already available
error=""
source <(/home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscription-by-service "$1")
if [ ${#error} -eq 0 ]; then
ip2tor="$1"
fi
}
# Options
OPTIONS=(ZAP_IOS "Zap Wallet (iOS)" \
ZAP_ANDROID "Zap Wallet (Android)" \
@ -81,10 +132,8 @@ if [ "${runBehindTor}" = "on" ]; then
OPTIONS+=(FULLY_NODED "Fully Noded (IOS+TOR)")
fi
# Additinal Options with no TOR
#if [ "${runBehindTor}" != "on" ]; then
OPTIONS+=(SENDMANY_ANDROID "SendMany (Android)")
#fi
# add SEND MANY APP
OPTIONS+=(SENDMANY_ANDROID "SendMany (Android)")
CHOICE=$(whiptail --clear --title "Choose Mobile Wallet" --menu "" 14 50 8 "${OPTIONS[@]}" 2>&1 >/dev/tty)
@ -107,6 +156,7 @@ case $CHOICE in
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-GRPC-API
/home/admin/config.scripts/bonus.lndconnect.sh shango-ios ${connect}
exit 1;
;;
@ -121,11 +171,11 @@ case $CHOICE in
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-GRPC-API
/home/admin/config.scripts/bonus.lndconnect.sh shango-android ${connect}
exit 1;
;;
ZAP_IOS)
choose_IP_or_TOR
appstoreLink="https://apps.apple.com/us/app/zap-bitcoin-lightning-wallet/id1406311960"
/home/admin/config.scripts/blitz.lcd.sh qr ${appstoreLink}
whiptail --title "Install Testflight and Zap on your iOS device" \
@ -136,22 +186,30 @@ case $CHOICE in
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-GRPC-API
# see https://github.com/rootzoll/raspiblitz/issues/1001#issuecomment-634580257
#if [ ${#ip2tor} -eq 0 ]; then
# choose_IP_or_TOR
#fi
/home/admin/config.scripts/bonus.lndconnect.sh zap-ios ${connect}
exit 1;
;;
ZAP_ANDROID)
# choose IP or TOR --> function call
choose_IP_or_TOR
appstoreLink="https://play.google.com/store/apps/details?id=zapsolutions.zap"
/home/admin/config.scripts/blitz.lcd.sh qr ${appstoreLink}
whiptail --title "Install Zap from PlayStore on your Android device" \
--yes-button "continue" \
--no-button "link as QR code" \
--yesno "Find & install the Zap Wallet on the Android Play Store:\n\n${appstoreLink}\n\nEasiest way to install scan QR code on LCD with phone.\n\nWhen installed and started -> continue." 10 65
--yesno "Find & install the Zap Wallet on the Android Play Store:\n\n${appstoreLink}\n\nEasiest way to install scan QR code on LCD with phone.\n\nWhen installed and started -> continue." 10 67
if [ $? -eq 1 ]; then
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-GRPC-API
# see https://github.com/rootzoll/raspiblitz/issues/1001#issuecomment-634580257
#if [ ${#ip2tor} -eq 0 ]; then
# choose_IP_or_TOR
#fi
/home/admin/config.scripts/bonus.lndconnect.sh zap-android ${connect}
exit 1;
;;
@ -178,6 +236,7 @@ Please go to MAINMENU > SERVICES and activate KEYSEND first.
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-GRPC-API
/home/admin/config.scripts/bonus.lndconnect.sh sendmany-android ${connect}
exit 1;
;;
@ -192,12 +251,11 @@ Please go to MAINMENU > SERVICES and activate KEYSEND first.
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-REST-API
/home/admin/config.scripts/bonus.lndconnect.sh zeus-ios ${connect}
exit 1;
;;
ZEUS_ANDROID)
# choose IP or TOR --> function call
choose_IP_or_TOR
appstoreLink="https://play.google.com/store/apps/details?id=com.zeusln.zeus"
/home/admin/config.scripts/blitz.lcd.sh qr ${appstoreLink}
whiptail --title "Install Zeus on your Android Phone" \
@ -208,6 +266,10 @@ Please go to MAINMENU > SERVICES and activate KEYSEND first.
/home/admin/config.scripts/blitz.lcd.sh qr-console ${appstoreLink}
fi
/home/admin/config.scripts/blitz.lcd.sh hide
checkIP2TOR LND-REST-API
if [ ${#ip2tor} -eq 0 ]; then
choose_IP_or_TOR
fi
/home/admin/config.scripts/bonus.lndconnect.sh zeus-android ${connect}
exit 1;
;;

View file

@ -129,7 +129,7 @@ patch()
clear
case $CHOICE in
PATCH)
sudo -u admin /home/admin/XXsyncScripts.sh
sudo -u admin /home/admin/XXsyncScripts.sh -run
sleep 4
whiptail --title " Patching/Syncing " --yes-button "Reboot" --no-button "Skip Reboot" --yesno " OK patching/syncing done.

Binary file not shown.

View file

@ -6,6 +6,15 @@
# IF YOU WANT TO UPDATE YOUR RASPIBLITZ:
# https://github.com/rootzoll/raspiblitz/blob/master/FAQ.md#how-to-update-my-raspiblitz-after-version-098
# command info
if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "-help" ]; then
echo "FOR DEVELOPMENT USE ONLY!"
echo "RaspiBlitz Sync Scripts"
echo "XXsyncScripts.sh info"
echo "XXsyncScripts.sh [-run|-clean|-install] branch [repo]"
exit 1
fi
cd /home/admin/raspiblitz
source /mnt/hdd/raspiblitz.conf 2>/dev/null
@ -13,7 +22,7 @@ source /mnt/hdd/raspiblitz.conf 2>/dev/null
activeGitHubUser=$(sudo -u admin cat /home/admin/raspiblitz/.git/config | grep "url = " | cut -d "=" -f2 | cut -d "/" -f4)
activeBranch=$(git branch | grep \* | cut -d ' ' -f2)
# if parameter is "info" just give back basic info about sync
# if parameter is "info" just give back basic info about sync
if [ "$1" == "info" ]; then
echo "activeGitHubUser='${activeGitHubUser}'"
echo "activeBranch='${activeBranch}'"
@ -24,6 +33,10 @@ fi
clean=0
wantedBranch="$1"
wantedGitHubUser="$2"
if [ "${wantedBranch}" = "-run" ]; then
wantedBranch="${activeBranch}"
wantedGitHubUser="${activeGitHubUser}"
fi
if [ "${wantedBranch}" = "-clean" ]; then
clean=1
wantedBranch="$2"
@ -84,6 +97,7 @@ if [ ${#wantedBranch} -gt 0 ]; then
else
echo ""
echo "USAGE-INFO: ./XXsyncScripts.sh '[BRANCHNAME]'"
exit 1
fi
origin=$(git remote -v | grep 'origin' | tail -n1)
@ -137,7 +151,7 @@ else
blitzpy_wheel=$(ls -trR /home/admin/raspiblitz/home.admin/BlitzPy/dist | grep -E "*any.whl" | tail -n 1)
blitzpy_version=$(echo ${blitzpy_wheel} | grep -oE "([0-9]\.[0-9]\.[0-9])")
echo "# BlitzPy changed --> UPDATING to Version ${blitzpy_version}"
sudo -H /usr/bin/python -m pip install "/home/admin/raspiblitz/home.admin/BlitzPy/dist/${blitzpy_wheel}" >/dev/null 2>&1
sudo -H /usr/bin/python -m pip install "/home/admin/raspiblitz/home.admin/BlitzPy/dist/${blitzpy_wheel}" >/dev/null 2>&1
fi
if [ "${touchscreen}" = "1" ]; then

View file

@ -140,7 +140,8 @@ do
if [ ${#dynDomain} -gt 0 ]; then
echo "restart LND with new environment config"
# restart and let to auto-unlock (if activated) do the rest
sudo systemctl restart lnd.service
sudo systemctl stop lnd
sudo systemctl start lnd
fi
# 2) trigger update if dnyamic domain (if set)
@ -247,13 +248,24 @@ do
fi
fi
###############################
# SUBSCRIPTION RENWES
###############################
# check every 10min
recheckSubscription=$((($counter % 600)+1))
if [ ${recheckSubscription} -eq 1 ]; then
# IP2TOR subscriptions (that will need renew in next 20min = 1200 secs)
/home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscriptions-renew 1200
fi
###############################
# RAID data check (BRTFS)
###############################
# see https://github.com/rootzoll/raspiblitz/issues/360#issuecomment-467698260
# check every hour
recheckRAID=$((($counter % 360)+1))
recheckRAID=$((($counter % 3600)+1))
if [ ${recheckRAID} -eq 1 ]; then
# check if raid is active
@ -285,11 +297,7 @@ do
if [ ${locked} -gt 0 ]; then
echo "STARTING AUTO-UNLOCK ..."
# building REST command
passwordC=$(sudo cat /root/lnd.autounlock.pwd)
command="sudo python3 /home/admin/config.scripts/lnd.unlock.py '${passwordC}'"
bash -c "${command}"
sudo /home/admin/config.scripts/lnd.unlock.sh
fi
fi

View file

@ -506,6 +506,18 @@ else
echo "OK: Temp cleaned" >> $logFile
fi
######################################
# PREPARE SUBSCRIPTIONS DATA DIRECTORY
######################################
if [ -d "/mnt/hdd/app-data/subscrptions" ]; then
echo "OK: subscription data directory exists"
else
echo "CREATE: subscription data directory"
sudo mkdir /mnt/hdd/app-data/subscriptions
sudo chown admin:admin /mnt/hdd/app-data/subscriptions
fi
################################
# IDENTIFY BASEIMAGE
################################

View file

@ -1,2 +1,2 @@
# RaspiBlitz Version - always [main].[sub]
codeVersion="1.5"
codeVersion="1.6.0rc0"

View file

@ -9,6 +9,7 @@ import time
import datetime, time
import codecs, grpc, os
from pathlib import Path
import toml
from blitzpy import RaspiBlitzConfig
@ -20,34 +21,38 @@ from lndlibs import rpc_pb2_grpc as rpcstub
# display config script info
if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "help":
print("# manage ip2tor subscriptions for raspiblitz")
print("# blitz.ip2tor.py menu")
print("# blitz.ip2tor.py shop-list [shopurl]")
print("# blitz.ip2tor.py shop-order [shopurl] [hostid] [toraddress:port] [duration] [msats]")
print("# blitz.ip2tor.py subscriptions-list")
print("# blitz.ip2tor.py subscriptions-renew [secondsBeforeSuspend]")
print("# blitz.ip2tor.py subscription-cancel [id]")
print("# blitz.subscriptions.ip2tor.py create-ssh-dialog [servicename] [toraddress] [torport]")
print("# blitz.subscriptions.ip2tor.py shop-list [shopurl]")
print("# blitz.subscriptions.ip2tor.py shop-order [shopurl] [servicename] [hostid] [toraddress:port] [duration] [msatsFirst] [msatsNext] [?description]")
print("# blitz.subscriptions.ip2tor.py subscriptions-list")
print("# blitz.subscriptions.ip2tor.py subscriptions-renew [secondsBeforeSuspend]")
print("# blitz.subscriptions.ip2tor.py subscription-cancel [id]")
print("# blitz.subscriptions.ip2tor.py subscription-by-service [servicename]")
sys.exit(1)
####### BASIC SETTINGS #########
cfg = RaspiBlitzConfig()
session = requests.session()
if Path("/mnt/hdd/raspiblitz.conf").is_file():
print("# blitz.ip2tor.py")
cfg = RaspiBlitzConfig()
cfg.reload()
ENV="PROD"
#DEFAULT_SHOPURL="shopdeu2vdhazvmllyfagdcvlpflzdyt5gwftmn4hjj3zw2oyelksaid.onion"
DEFAULT_SHOPURL="shop.ip2t.org"
LND_IP="127.0.0.1"
LND_ADMIN_MACAROON_PATH="/mnt/hdd/app-data/lnd/data/chain/{0}/{1}net/admin.macaroon".format(cfg.network,cfg.chain)
LND_ADMIN_MACAROON_PATH="/mnt/hdd/app-data/lnd/data/chain/{0}/{1}net/admin.macaroon".format(cfg.network.value,cfg.chain.value)
LND_TLS_PATH="/mnt/hdd/app-data/lnd/tls.cert"
# make sure to make requests thru TOR 127.0.0.1:9050
session.proxies = {'http': 'socks5h://127.0.0.1:9050', 'https': 'socks5h://127.0.0.1:9050'}
SUBSCRIPTIONS_FILE="/mnt/hdd/app-data/subscriptions/subscriptions.toml"
else:
ENV="DEV"
print("# blitz.ip2tor.py (development env)")
DEFAULT_SHOPURL="shop.ip2t.org"
LND_IP="192.168.178.95"
LND_ADMIN_MACAROON_PATH="/Users/rotzoll/Downloads/RaspiBlitzCredentials/admin.macaroon"
LND_TLS_PATH="/Users/rotzoll/Downloads/RaspiBlitzCredentials/tls.cert"
SUBSCRIPTIONS_FILE="/Users/rotzoll/Downloads/RaspiBlitzCredentials/subscriptions.toml"
####### HELPER CLASSES #########
@ -73,7 +78,7 @@ def handleException(e):
sys.exit(1)
def parseDate(datestr):
return datetime.datetime.strptime(datestr,"%Y-%m-%dT%H:%M:%S.%fZ")
return datetime.datetime.strptime(datestr,"%Y-%m-%dT%H:%M:%SZ")
def secondsLeft(dateObj):
return round((dateObj - datetime.datetime.utcnow()).total_seconds())
@ -201,6 +206,7 @@ def apiPlaceOrderExtension(session, shopurl, bridgeid):
raise BlitzError("failed HTTP code",response.status_code)
# parse & validate data
print("# parse")
try:
jData = json.loads(response.content)
if len(jData['po_id']) == 0:
@ -315,7 +321,7 @@ def shopList(shopUrl):
shopUrl=normalizeShopUrl(shopUrl)
return apiGetHosts(session, shopUrl)
def shopOrder(shopUrl, hostid, torTarget, duration, msatsFirst):
def shopOrder(shopUrl, hostid, servicename, torTarget, duration, msatsFirst, msatsNext, description=""):
print("#### Placeing order ...")
shopUrl=normalizeShopUrl(shopUrl)
@ -346,7 +352,7 @@ def shopOrder(shopUrl, hostid, torTarget, duration, msatsFirst):
print("# amount as advertised: {0}".format(msatsFirst))
print("# amount in invoice is: {0}".format(paymentRequestDecoded.num_msat))
if int(msatsFirst) < int(paymentRequestDecoded.num_msat):
raise BlitzError("invoice other amount than advertised", "advertised({0}) invoice({1})".format(msatsFirst, paymentRequestDecoded.num_msat))
raise BlitzError("invoice bigger amount than advertised", "advertised({0}) invoice({1})".format(msatsFirst, paymentRequestDecoded.num_msat))
print("#### Paying invoice ...")
payedInvoice = lndPayInvoice(paymentRequestStr)
@ -364,23 +370,62 @@ def shopOrder(shopUrl, hostid, torTarget, duration, msatsFirst):
if loopCount > 60:
raise BlitzError("timeout bridge not getting ready", bridge)
# get data from ready bride
bridge_suspendafter = bridge['suspend_after']
bridge_port = bridge['port']
print("#### Check if duration delivered is as advertised ...")
secondsDelivered=secondsLeft(parseDate(bridge_suspendafter))
contract_breached = False
warning_text = ""
secondsDelivered=secondsLeft(parseDate(bridge['suspend_after']))
print("# delivered({0}) promised({1})".format(secondsDelivered, duration))
if (secondsDelivered + 600) < int(duration):
bridge['contract_breached'] = True
bridge['warning'] = "delivered duration shorter than advertised"
else:
bridge['contract_breached'] = False
contract_breached = True
warning_text = "delivered duration shorter than advertised"
print("# OK - BRIDGE READY: {0}:{1} -> {2}".format(bridge_ip, bridge_port, torTarget))
return bridge
# create subscription data for storage
subscription = {}
subscription['type'] = "ip2tor-v1"
subscription['id'] = bridge['id']
subscription['name'] = servicename
subscription['shop'] = shopUrl
subscription['active'] = True
subscription['ip'] = bridge_ip
subscription['port'] = bridge['port']
subscription['duration'] = int(duration)
subscription['price_initial'] = int(msatsFirst)
subscription['price_extension'] = int(msatsNext)
subscription['price_total'] = int(paymentRequestDecoded.num_msat)
subscription['time_created'] = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
subscription['time_lastupdate'] = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
subscription['suspend_after'] = bridge['suspend_after']
subscription['description'] = str(description)
subscription['contract_breached'] = contract_breached
subscription['warning'] = warning_text
subscription['tor'] = torTarget
# load, add and store subscriptions
try:
if Path(SUBSCRIPTIONS_FILE).is_file():
print("# load toml file")
subscriptions = toml.load(SUBSCRIPTIONS_FILE)
else:
print("# new toml file")
subscriptions = {}
subscriptions['subscriptions_ip2tor'] = []
subscriptions['subscriptions_ip2tor'].append(subscription)
subscriptions['shop_ip2tor'] = shopUrl
with open(SUBSCRIPTIONS_FILE, 'w') as writer:
writer.write(toml.dumps(subscriptions))
writer.close()
def subscriptionExtend(shopUrl, bridgeid, durationAdvertised, msatsFirst):
except Exception as e:
eprint(e)
raise BlitzError("fail on subscription storage",subscription, e)
print("# OK - BRIDGE READY: {0}:{1} -> {2}".format(bridge_ip, subscription['port'], torTarget))
return subscription
def subscriptionExtend(shopUrl, bridgeid, durationAdvertised, msatsNext, bridge_suspendafter):
warningTXT=""
contract_breached=False
print("#### Placing extension order ...")
shopUrl=normalizeShopUrl(shopUrl)
@ -408,36 +453,62 @@ def subscriptionExtend(shopUrl, bridgeid, durationAdvertised, msatsFirst):
print("# amount as advertised: {0}".format(msatsNext))
print("# amount in invoice is: {0}".format(paymentRequestDecoded.num_msat))
if int(msatsNext) < int(paymentRequestDecoded.num_msat):
raise BlitzError("invoice other amount than advertised", "advertised({0}) invoice({1})".format(msatsNext, paymentRequestDecoded.num_msat))
raise BlitzError("invoice bigger amount than advertised", "advertised({0}) invoice({1})".format(msatsNext, paymentRequestDecoded.num_msat))
print("#### Paying invoice ...")
payedInvoice = lndPayInvoice(paymentRequestStr)
print("#### Check if bride was extended ...")
print("#### Check if bridge was extended ...")
loopCount=0
while True:
time.sleep(3)
loopCount+=1
print("## Loop {0}".format(loopCount))
bridge = apiGetBridgeStatus(session, shopUrl, bridgeid)
if bridge['suspend_after'] != bridge_suspendafter:
try:
bridge = apiGetBridgeStatus(session, shopUrl, bridgeid)
if bridge['suspend_after'] != bridge_suspendafter:
break
except Exception as e:
eprint(e)
print("# EXCEPTION on apiGetBridgeStatus")
if loopCount > 60:
warningTXT="timeout on last payed extension"
contract_breached=True
break
if loopCount > 60:
raise BlitzError("timeout on waiting for extending bridge", bridge)
print("#### Check if extension duration is as advertised ...")
secondsLeftOld = secondsLeft(parseDate(bridge_suspendafter))
secondsLeftNew = secondsLeft(parseDate(bridge['suspend_after']))
secondsExtended = secondsLeftNew - secondsLeftOld
print("# secondsExtended({0}) promised({1})".format(secondsExtended, durationAdvertised))
if secondsExtended < int(durationAdvertised):
bridge['contract_breached'] = True
bridge['warning'] = "delivered duration shorter than advertised"
else:
bridge['contract_breached'] = False
if not contract_breached:
print("#### Check if extension duration is as advertised ...")
secondsLeftOld = secondsLeft(parseDate(bridge_suspendafter))
secondsLeftNew = secondsLeft(parseDate(bridge['suspend_after']))
secondsExtended = secondsLeftNew - secondsLeftOld
print("# secondsExtended({0}) promised({1})".format(secondsExtended, durationAdvertised))
if secondsExtended < int(durationAdvertised):
contract_breached = True
warningTXT = "delivered duration shorter than advertised"
# load, update and store subscriptions
try:
print("# load toml file")
subscriptions = toml.load(SUBSCRIPTIONS_FILE)
for idx, subscription in enumerate(subscriptions['subscriptions_ip2tor']):
if subscription['id'] == bridgeid:
subscription['suspend_after'] = str(bridge['suspend_after'])
subscription['time_lastupdate'] = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
subscription['price_total'] += int(paymentRequestDecoded.num_msat)
subscription['contract_breached'] = contract_breached
subscription['warning'] = warningTXT
if contract_breached:
subscription['active'] = False
with open(SUBSCRIPTIONS_FILE, 'w') as writer:
writer.write(toml.dumps(subscriptions))
writer.close()
break
except Exception as e:
eprint(e)
raise BlitzError("fail on subscription storage",subscription, e)
print("# BRIDGE GOT EXTENDED: {0} -> {1}".format(bridge_suspendafter, bridge['suspend_after']))
return bridge
def menuMakeSubscription(blitzServiceName, torAddress, torPort):
@ -446,7 +517,15 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
############################
# PHASE 1: Enter Shop URL
# see if user had before entered another shop of preference
shopurl = DEFAULT_SHOPURL
try:
subscriptions = toml.load(SUBSCRIPTIONS_FILE)
shopurl = subscriptions['shop_ip2tor']
print("# using last shop url set in subscriptions.toml")
except Exception as e:
print("# using default shop url")
while True:
# input shop url
@ -484,7 +563,7 @@ Try again later, enter another address or cancel.
###############################
# PHASE 2: SELECT SUBSCRIPTION
# create menu to select shop - TODO: also while loop list & detail until cancel or subscription
# create menu to select shop
host=None
choices = []
for idx, hostEntry in enumerate(hosts):
@ -520,7 +599,7 @@ Every next time it would cost: {2} sats
If you AGREE you will subscribe to this service.
You will get a port on the IP {3} that will
forward to your RaspiBlitz TOR address:
forward to your RaspiBlitz TOR address for '{7}':
{4}
You can cancel the subscription anytime under
@ -540,9 +619,11 @@ More information on the service you can find under:
host['ip'],
torTarget,
host['terms_of_service'],
host['terms_of_service_url'])
host['terms_of_service_url'],
blitzServiceName
)
code = d.msgbox(text, title=host['name'], ok_label="Back", extra_button=True, extra_label="AGREE" ,width=70, height=30)
code = d.msgbox(text, title=host['name'], ok_label="Back", extra_button=True, extra_label="AGREE" ,width=75, height=30)
# if user AGREED break loop and continue with selected host
if code == "extra": break
@ -550,14 +631,17 @@ More information on the service you can find under:
############################
# PHASE 3: Make Subscription
description = "{0} / {1} / {2}".format(host['name'], host['terms_of_service'], host['terms_of_service_url'])
try:
os.system('clear')
bridge = shopOrder(shopurl, host['id'], torTarget, host['tor_bridge_duration'], host['tor_bridge_price_initial'])
subscription = shopOrder(shopurl, host['id'], blitzServiceName, torTarget, host['tor_bridge_duration'], host['tor_bridge_price_initial'],host['tor_bridge_price_extension'],description)
except BlitzError as be:
if be.errorShort == "timeout on waiting for extending bridge":
if (be.errorShort == "timeout on waiting for extending bridge" or
be.errorShort == "fail on subscription storage") :
# error happend after payment
Dialog(dialog="dialog",autowidgetsize=True).msgbox('''
@ -587,57 +671,77 @@ Unkown Error happend - please report to developers:
'''.format(str(e)),title="Exception on Subscription")
sys.exit(1)
# if LND REST or LND GRPS service ... add bridge IP to TLS
if servicename == "LND-REST-API" or servicename == "LND-GRPC-API":
os.system("sudo /home/admin/config.scripts/lnd.tlscert.sh ip-add {0}".format(subscription['ip']))
os.system("sudo /home/admin/config.scripts/lnd.credentials.sh reset tls")
os.system("sudo /home/admin/config.scripts/lnd.credentials.sh sync")
# warn user if not delivered as advertised
if bridge['contract_breached']:
if subscription['contract_breached']:
Dialog(dialog="dialog",autowidgetsize=True).msgbox('''
The service was payed & delivered, but RaspiBlitz detected:
{0}
You may want to consider to cancel the subscription later.
'''.format(bridge['warning'],title="Warning"))
# TODO: persist subscription in list
'''.format(subscription['warning'],title="Warning"))
# Give final result feedback to user
Dialog(dialog="dialog",autowidgetsize=True).msgbox('''
OK your service is ready & your subscription is active.
You payed {0} sats for the first {1} hours.
Next AUTOMATED PAYMENT will be {2} sats.
Next AUTOMATED PAYMENTS will be {2} sats each.
Your service '{3}' should now publicly be reachable under:
{4}:{5}
Please test now if the service is performing as promised.
If not - dont forget to cancel the subscription under:
MAIN MENU > SUBSCRIPTIONS > MY SUBSCRIPTIONS
'''.format(be.errorShort),title="Subscription Active")
MAIN MENU > Manage Subscriptions > My Subscriptions
'''.format(
host['tor_bridge_price_initial_sats'],
host['tor_bridge_duration_hours'],
host['tor_bridge_price_extension_sats'],
blitzServiceName,
subscription['ip'],
subscription['port'])
,title="Subscription Active")
####### COMMANDS #########
###############
# MENU
# CREATE SSH DIALOG
# use for ssh shell menu
###############
if sys.argv[1] == "menu":
if sys.argv[1] == "create-ssh-dialog":
# check parameters
try:
if len(sys.argv) <= 4: raise BlitzError("incorrect parameters","")
servicename = sys.argv[2]
toraddress = sys.argv[3]
port = sys.argv[4]
except Exception as e:
handleException(e)
# late imports - so that rest of script can run also if dependency is not available
from dialog import Dialog
menuMakeSubscription("RTL", "s7foqiwcstnxmlesfsjt7nlhwb2o6w44hc7glv474n7sbyckf76wn6id.onion", "80")
menuMakeSubscription(servicename, toraddress, port)
sys.exit()
###############
# SHOP LIST
# call from web interface
###############
###############
if sys.argv[1] == "shop-list":
# check parameters
try:
if len(sys.argv) <= 2: raise BlitzError("incorrect parameters","")
shopurl = sys.argv[2]
except Exception as e:
handleException(e)
@ -661,24 +765,29 @@ if sys.argv[1] == "shop-order":
# check parameters
try:
if len(sys.argv) <= 8: raise BlitzError("incorrect parameters","")
shopurl = sys.argv[2]
hostid = sys.argv[3]
toraddress = sys.argv[4]
duration = sys.argv[5]
msats = sys.argv[6]
servicename = sys.argv[3]
hostid = sys.argv[4]
toraddress = sys.argv[5]
duration = sys.argv[6]
msatsFirst = sys.argv[7]
msatsNext = sys.argv[8]
if len(sys.argv) >=10:
description = sys.argv[9]
else:
description = ""
except Exception as e:
handleException(e)
# get data
try:
bridge = shopOrder(shopurl, hostid, toraddress, duration, msats)
subscription = shopOrder(shopurl, hostid, servicename, toraddress, duration, msatsFirst, msatsNext, description)
except Exception as e:
handleException(e)
# TODO: persist subscription
# output json ordered bridge
print(json.dumps(bridge, indent=2))
print(json.dumps(subscription, indent=2))
sys.exit()
#######################
@ -689,9 +798,13 @@ if sys.argv[1] == "shop-order":
if sys.argv[1] == "subscriptions-list":
try:
# TODO: JSON output of list with all subscrptions
print("TODO: implement")
if Path(SUBSCRIPTIONS_FILE).is_file():
subs = toml.load(SUBSCRIPTIONS_FILE)
else:
subs = {}
subs['subscriptions_ip2tor'] = []
print(json.dumps(subs, indent=2))
except Exception as e:
handleException(e)
@ -705,44 +818,136 @@ if sys.argv[1] == "subscriptions-list":
if sys.argv[1] == "subscriptions-renew":
print("# RUNNING subscriptions-renew")
# check parameters
try:
secondsBeforeSuspend = sys.argv[2]
secondsBeforeSuspend = int(sys.argv[2])
if secondsBeforeSuspend < 0: secondsBeforeSuspend = 0
except Exception as e:
handleException(e)
print("# running with secondsBeforeSuspend=0")
secondsBeforeSuspend = 0
# TODO: check if any active subscrpitions are below the secondsBeforeSuspend - if yes extend
print("TODO: implement")
sys.exit(1)
# get date
# check if any active subscrpitions are below the secondsBeforeSuspend - if yes extend
try:
bridge = subscriptionExtend(shopUrl, bridgeid, durationAdvertised, msatsFirst)
if not Path(SUBSCRIPTIONS_FILE).is_file():
print("# no subscriptions")
sys.exit(0)
subscriptions = toml.load(SUBSCRIPTIONS_FILE)
for idx, subscription in enumerate(subscriptions['subscriptions_ip2tor']):
try:
if subscription['active'] and subscription['type'] == "ip2tor-v1":
secondsToRun = secondsLeft(parseDate(subscription['suspend_after']))
if secondsToRun < secondsBeforeSuspend:
print("# RENEW: subscription {0} with {1} seconds to run".format(subscription['id'],secondsToRun))
subscriptionExtend(
subscription['shop'],
subscription['id'],
subscription['duration'],
subscription['price_extension'],
subscription['suspend_after']
)
else:
print("# GOOD: subscription {0} with {1} seconds to run".format(subscription['id'],secondsToRun))
except BlitzError as be:
# write error into subscription warning
subs = toml.load(SUBSCRIPTIONS_FILE)
for idx, sub in enumerate(subs['subscriptions_ip2tor']):
if sub['id'] == subscription['id']:
sub['warning'] = "Exception on Renew: {0}".format(be.errorShort)
if be.errorShort == "invoice bigger amount than advertised":
sub['contract_breached'] = True
sub['active'] = False
with open(SUBSCRIPTIONS_FILE, 'w') as writer:
writer.write(toml.dumps(subs))
writer.close()
break
print("# BLITZERROR on subscriptions-renew of subscription index {0}: {1}".format(idx, be.errorShort))
print("# {0}".format(be.errorShort))
except Exception as e:
print("# EXCEPTION on subscriptions-renew of subscription index {0}".format(idx))
eprint(e)
except Exception as e:
handleException(e)
# TODO: persist subscription
# output - not needed only for debug logs
print("# DONE subscriptions-renew")
sys.exit(1)
#######################
# SUBSCRIPTION CANCEL
# call in intervalls from background process
#######################
if sys.argv[1] == "subscription-cancel":
# check parameters
try:
# TODO: JSON output of list with all subscrptions
print("TODO: implement")
if len(sys.argv) <= 2: raise BlitzError("incorrect parameters","")
subscriptionID = sys.argv[2]
except Exception as e:
handleException(e)
try:
subs = toml.load(SUBSCRIPTIONS_FILE)
newList = []
for idx, sub in enumerate(subs['subscriptions_ip2tor']):
if sub['id'] != subscriptionID:
newList.append(sub)
subs['subscriptions_ip2tor'] = newList
# persist change
with open(SUBSCRIPTIONS_FILE, 'w') as writer:
writer.write(toml.dumps(subs))
writer.close()
print(json.dumps(subs, indent=2))
except Exception as e:
handleException(e)
sys.exit(0)
#######################
# GET ADDRESS BY SERVICENAME
# gets called by other scripts to check if service has a ip2tor bridge address
# output is bash key/value style so that it can be imported with source
#######################
if sys.argv[1] == "subscription-by-service":
# check parameters
try:
if len(sys.argv) <= 2: raise BlitzError("incorrect parameters","")
servicename = sys.argv[2]
except Exception as e:
handleException(e)
try:
if os.path.isfile(SUBSCRIPTIONS_FILE):
subs = toml.load(SUBSCRIPTIONS_FILE)
for idx, sub in enumerate(subs['subscriptions_ip2tor']):
if sub['active'] and sub['name'] == servicename:
print("type='{0}'".format(sub['type']))
print("ip='{0}'".format(sub['ip']))
print("port='{0}'".format(sub['port']))
print("tor='{0}'".format(sub['tor']))
sys.exit(0)
print("error='not found'")
sys.exit(0)
except Exception as e:
handleException(e)
sys.exit(1)
# unkown command
print("# unkown command")

View file

@ -0,0 +1,258 @@
#!/usr/bin/python3
########################################################
# SSH Dialogs to manage Subscriptions on the RaspiBlitz
########################################################
import sys
import math
import time
import toml
import os
import subprocess
from dialog import Dialog
from blitzpy import RaspiBlitzConfig
# constants for standard services
LND_REST_API = "LND-REST-API"
LND_GRPC_API = "LND-GRPC-API"
# load config
cfg = RaspiBlitzConfig()
cfg.reload()
# basic values
SUBSCRIPTIONS_FILE="/mnt/hdd/app-data/subscriptions/subscriptions.toml"
####### HELPER FUNCTIONS #########
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def parseDateIP2TORSERVER(datestr):
return datetime.datetime.strptime(datestr,"%Y-%m-%dT%H:%M:%S.%fZ")
def secondsLeft(dateObj):
return round((dateObj - datetime.datetime.utcnow()).total_seconds())
####### SSH MENU FUNCTIONS #########
def mySubscriptions():
# check if any subscriptions are available
countSubscriptions=0
try:
subs = toml.load(SUBSCRIPTIONS_FILE)
countSubscriptions += len(subs['subscriptions_ip2tor'])
except Exception as e: pass
if countSubscriptions == 0:
Dialog(dialog="dialog",autowidgetsize=True).msgbox('''
You have no active or inactive subscriptions.
''',title="Info")
return
# load subscriptions and make dialog choices out of it
choices = []
lookup = {}
lookupIndex=0
subs = toml.load(SUBSCRIPTIONS_FILE)
# list ip2tor subscriptions
for sub in subs['subscriptions_ip2tor']:
# remember subscription under lookupindex
lookupIndex += 1
lookup[str(lookupIndex)]=sub
# add to dialog choices
if sub['active']:
activeState="active"
else:
activeState="in-active"
name="IP2TOR Bridge for {0}".format(sub['name'])
choices.append( ("{0}".format(lookupIndex), "{0} ({1})".format(name.ljust(30), activeState)) )
# show menu with options
d = Dialog(dialog="dialog",autowidgetsize=True)
d.set_background_title("RaspiBlitz Subscriptions")
code, tag = d.menu(
"\nYou have the following subscriptions - select for details:",
choices=choices, cancel_label="Back", width=65, height=15, title="My Subscriptions")
# if user chosses CANCEL
if code != d.OK: return
# get data of selected subscrption
selectedSub = lookup[str(tag)]
# show details of selected
d = Dialog(dialog="dialog",autowidgetsize=True)
d.set_background_title("My Subscriptions")
if selectedSub['type'] == "ip2tor-v1":
if len(selectedSub['warning']) > 0:
selectedSub['warning'] = "\n{0}".format(selectedSub['warning'])
text='''
This is a IP2TOR subscription bought on {initdate} at
{shop}
It forwards from the public address {publicaddress} to
{toraddress}
for the RaspiBlitz service: {service}
It will renew every {renewhours} hours for {renewsats} sats.
Total payed so far: {totalsats} sats
The state of the subscription is: {active} {warning}
The following additional information is available:
{description}
'''.format( initdate=selectedSub['time_created'],
shop=selectedSub['shop'],
publicaddress="{0}:{1}".format(selectedSub['ip'],selectedSub['port']),
toraddress=selectedSub['tor'],
renewhours=(round(int(selectedSub['duration'])/3600)),
renewsats=(round(int(selectedSub['price_extension'])/1000)),
totalsats=(round(int(selectedSub['price_extension'])/1000)),
active= "ACTIVE" if selectedSub['active'] else "NOT ACTIVE",
warning=selectedSub['warning'],
description=selectedSub['description'],
service=selectedSub['name']
)
if selectedSub['active']:
extraLable = "CANCEL SUBSCRIPTION"
else:
extraLable = "DELETE SUBSCRIPTION"
code = d.msgbox(text, title="Subscription Detail", ok_label="Back", extra_button=True, extra_label=extraLable ,width=75, height=30)
# user wants to delete this subscription
# call the responsible sub script for deletion just in case any subscription needs to do some extra api calls when canceling
if code == "extra":
os.system("clear")
if selectedSub['type'] == "ip2tor-v1":
cmd="python /home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscription-cancel {0}".format(selectedSub['id'])
print("# running: {0}".format(cmd))
os.system(cmd)
time.sleep(2)
else:
print("# FAIL: unknown subscription type")
time.sleep(3)
# loop until no more subscriptions or user chooses CANCEL on subscription list
mySubscriptions()
####### SSH MENU #########
choices = []
choices.append( ("LIST","My Subscriptions") )
choices.append( ("NEW1","+ new IP2TOR Bridge") )
d = Dialog(dialog="dialog",autowidgetsize=True)
d.set_background_title("RaspiBlitz Subscriptions")
code, tag = d.menu(
"\nCheck existing subscriptions or create new:",
choices=choices, width=50, height=10, title="Subscription Management")
# if user chosses CANCEL
if code != d.OK:
sys.exit(0)
####### MANAGE SUBSCRIPTIONS #########
if tag == "LIST":
mySubscriptions()
sys.exit(0)
####### NEW IP2TOR BRIDGE #########
if tag == "NEW1":
# check if Blitz is running behind TOR
cfg.reload()
if not cfg.run_behind_tor.value:
Dialog(dialog="dialog",autowidgetsize=True).msgbox('''
The IP2TOR service just makes sense if you run
your RaspiBlitz behind TOR.
''',title="Info")
sys.exit(1)
# check for which standard services already a active bridge exists
lnd_rest_api=False
lnd_grpc_api=False
try:
if os.path.isfile(SUBSCRIPTIONS_FILE):
subs = toml.load(SUBSCRIPTIONS_FILE)
for sub in subs['subscriptions_ip2tor']:
if not sub['active']: next
if sub['active'] and sub['name'] == LND_REST_API: lnd_rest_api=True
if sub['active'] and sub['name'] == LND_GRPC_API: lnd_grpc_api=True
except Exception as e:
print(e)
# ask user for which RaspiBlitz service the bridge should be used
choices = []
choices.append( ("REST","LND REST API {0}".format("--> ALREADY BRIDGED" if lnd_rest_api else "")) )
choices.append( ("GRPC","LND gRPC API {0}".format("--> ALREADY BRIDGED" if lnd_grpc_api else "")) )
choices.append( ("SELF","Create a custom IP2TOR Bridge") )
d = Dialog(dialog="dialog",autowidgetsize=True)
d.set_background_title("RaspiBlitz Subscriptions")
code, tag = d.menu(
"\nChoose RaspiBlitz Service to create Bridge for:",
choices=choices, width=60, height=10, title="Select Service")
# if user chosses CANCEL
if code != d.OK:
sys.exit(0)
servicename=None
torAddress=None
torPort=None
if tag == "REST":
# get TOR address for REST
servicename=LND_REST_API
torAddress = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lndrest8080/hostname'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
torPort=8080
if tag == "GRPC":
# get TOR address for GRPC
servicename=LND_GRPC_API
torAddress = subprocess.run(['sudo', 'cat', '/mnt/hdd/tor/lndrpc10009/hostname'], stdout=subprocess.PIPE).stdout.decode('utf-8').strip()
torPort=10009
if tag == "SELF":
servicename="CUSTOM"
try:
# get custom TOR address
code, text = d.inputbox(
"Enter TOR Onion-Address:",
height=10, width=60, init="",
title="IP2TOR Bridge Target")
text = text.strip()
os.system("clear")
if code != d.OK: sys.exit(0)
if len(text) == 0: sys.exit(0)
if text.find('.onion') < 0 or text.find(' ') > 0 :
print("Not a TOR Onion Address")
time.sleep(3)
sys.exit(0)
torAddress = text
# get custom TOR port
code, text = d.inputbox(
"Enter TOR Port Number:",
height=10, width=40, init="80",
title="IP2TOR Bridge Target")
text = text.strip()
os.system("clear")
if code != d.OK: sys.exit(0)
if len(text) == 0: sys.exit(0)
torPort = int(text)
except Exception as e:
print(e)
time.sleep(3)
sys.exit(1)
# run creating a new IP2TOR subscription
os.system("clear")
cmd="python /home/admin/config.scripts/blitz.subscriptions.ip2tor.py create-ssh-dialog {0} {1} {2}".format(servicename,torAddress,torPort)
print("# running: {0}".format(cmd))
os.system(cmd)
sys.exit(0)

View file

@ -45,6 +45,24 @@ else
echo "# lndconnect is already installed"
fi
#### CHECK IF IP2TOR BRIDGES ARE AVAILABLE
ip2torREST_IP=""
ip2torREST_PORT=""
error=""
source <(/home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscription-by-service LND-REST-API)
if [ ${#error} -eq 0 ]; then
ip2torREST_IP="${ip}"
ip2torREST_PORT="${port}"
fi
ip2torGRPC_IP=""
ip2torGRPC_PORT=""
error=""
source <(/home/admin/config.scripts/blitz.subscriptions.ip2tor.py subscription-by-service LND-GRPC-API)
if [ ${#error} -eq 0 ]; then
ip2torGRPC_IP="${ip}"
ip2torGRPC_PORT="${port}"
fi
#### ADAPT PARAMETERS BASED TARGETWALLET
# defaults
@ -53,6 +71,7 @@ host=""
port=""
extraparameter=""
supportsTOR=0
usingIP2TOR=""
if [ "${targetWallet}" = "zap-ios" ]; then
connector="lndconnect"
@ -64,6 +83,14 @@ if [ "${targetWallet}" = "zap-ios" ]; then
# normal ZAP uses gRPC ports
port="10009"
fi
if [ ${#ip2torGRPC_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-GRPC-API"
forceTOR=0
extraparameter=""
host="${ip2torGRPC_IP}"
port="${ip2torGRPC_PORT}"
fi
elif [ "${targetWallet}" = "zap-android" ]; then
connector="lndconnect"
@ -75,20 +102,44 @@ elif [ "${targetWallet}" = "zap-android" ]; then
# normal ZAP uses gRPC ports
port="10009"
fi
if [ ${#ip2torGRPC_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-GRPC-API"
forceTOR=0
extraparameter=""
host="${ip2torGRPC_IP}"
port="${ip2torGRPC_PORT}"
fi
elif [ "${targetWallet}" = "zeus-ios" ]; then
connector="lndconnect"
port="8080"
if [ ${#ip2torREST_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-REST-API"
forceTOR=0
extraparameter=""
host="${ip2torREST_IP}"
port="${ip2torREST_PORT}"
fi
if [ ${forceTOR} -eq 1 ]; then
echo "error='no tor support'"
exit 1
fi
port="8080"
elif [ "${targetWallet}" = "zeus-android" ]; then
connector="lndconnect"
port="8080"
if [ ${#ip2torREST_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-REST-API"
forceTOR=0
extraparameter=""
host="${ip2torREST_IP}"
port="${ip2torREST_PORT}"
fi
elif [ "${targetWallet}" = "sendmany-android" ]; then
@ -103,25 +154,49 @@ elif [ "${targetWallet}" = "sendmany-android" ]; then
forceTOR=0
fi
port="10009"
if [ ${#ip2torGRPC_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-GRPC-API"
forceTOR=0
extraparameter=""
host="${ip2torGRPC_IP}"
port="${ip2torGRPC_PORT}"
fi
elif [ "${targetWallet}" = "shango-ios" ]; then
connector="shango"
port="10009"
if [ ${#ip2torGRPC_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-GRPC-API"
forceTOR=0
extraparameter=""
host="${ip2torGRPC_IP}"
port="${ip2torGRPC_PORT}"
fi
if [ ${forceTOR} -eq 1 ]; then
echo "error='no tor support'"
exit 1
fi
port="10009"
elif [ "${targetWallet}" = "shango-android" ]; then
connector="shango"
port="10009"
if [ ${#ip2torGRPC_IP} -gt 0 ]; then
# when IP2TOR bridge is available - force using that
usingIP2TOR="LND-GRPC-API"
forceTOR=0
extraparameter=""
host="${ip2torGRPC_IP}"
port="${ip2torGRPC_PORT}"
fi
if [ ${forceTOR} -eq 1 ]; then
echo "error='no tor support'"
exit 1
fi
port="10009"
else
echo "error='unknown target wallet'"
exit 1
@ -130,7 +205,9 @@ fi
#### ADAPT PARAMETERS BASED RASPIBLITZ CONFIG
# get the local IP as default host
host=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
if [ ${#host} -eq 0 ]; then
host=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
fi
# change host to dynDNS if set
if [ ${#dynDomain} -gt 0 ]; then
@ -211,6 +288,9 @@ msg=""
if [ $(echo "${host}" | grep -c '192.168') -gt 0 ]; then
msg="Make sure you are on the same local network.\n(WLAN same as LAN - use WIFI not cell network on phone).\n\n"
fi
if [ ${#usingIP2TOR} -gt 0 ]; then
msg="Your IP2TOR bridge '${usingIP2TOR}' is used for this connection.\n\n"
fi
msg="You should now see the pairing QR code on the RaspiBlitz LCD.\n\n${msg}When you start the App choose to connect to your own node.\n(DIY / Remote-Node / lndconnect)\n\nClick on the 'Scan QR' button. Scan the QR on the LCD and <continue> or <console QRcode> to see it in this window."
whiptail --backtitle "Connecting Mobile Wallet" \
--title "Pairing by QR code" \

View file

@ -129,7 +129,7 @@ if [ "$1" = "0" ] || [ "$1" = "off" ]; then
fi
# refresh TLS cert
sudo /home/admin/config.scripts/lnd.newtlscert.sh
sudo /home/admin/config.scripts/lnd.tlscert.sh refresh
echo "may needs reboot to run normal again"
exit 0

View file

@ -188,7 +188,7 @@ if sys.argv[1] == "on":
newConfigHash=subprocess.getoutput("sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf")
if oldConfigHash != newConfigHash:
print("lnd.conf changed ... generating new TLS cert")
subprocess.call("sudo /home/admin/config.scripts/lnd.newtlscert.sh", shell=True)
subprocess.call(sudo /home/admin/config.scripts/lnd.tlscert.sh refresh", shell=True)
else:
print("lnd.conf unchanged... keep TLS cert")

View file

@ -49,9 +49,9 @@ Password C will be stored on the device.
echo "SYSTEMD RESTART LOG: lightning (LND)" > /home/admin/systemd.lightning.log
sudo systemctl restart lnd
sleep 4
result=$(sudo python /home/admin/config.scripts/lnd.unlock.py ${passwordC})
invalid=$(echo "${result}" | grep -c 'invalid')
if [ ${invalid} -gt 0 ];then
error=""
source <(sudo /home/admin/config.scripts/lnd.unlock.sh "$passwordC")
if [ ${error} -gt 0 ];then
echo "# PASSWORD C is wrong - try again or cancel"
sleep 3
sudo /home/admin/config.scripts/lnd.autounlock.sh on
@ -82,30 +82,6 @@ fi
# switch on
if [ "$1" = "1" ] || [ "$1" = "on" ]; then
# get hash of lnd.conf before edit (to detect if changed later)
md5HashBefore=$(sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf)
# make sure config values are uncommented
sudo sed -i "s/^#restlisten=.*/restlisten=/g" /mnt/hdd/lnd/lnd.conf
# make sure config values exits
exists=$(sudo cat /mnt/hdd/lnd/lnd.conf | grep -c 'restlisten=')
if [ ${exists} -eq 0 ]; then
sudo sed -n -i 'p;4a restlisten=' /mnt/hdd/lnd/lnd.conf
fi
# set needed config values
sudo sed -i "s/^restlisten=.*/restlisten=0.0.0.0:8080/g" /mnt/hdd/lnd/lnd.conf
# refresh TLS cert (if lnd.conf was changed)
md5HashAfter=$(sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf)
if [ "${md5HashAfter}" != "${md5HashBefore}" ]; then
echo "# lnd.conf changed - TLS certs need refreshing"
sudo /home/admin/config.scripts/lnd.newtlscert.sh
else
echo "# lnd.conf NOT changed - keep TLS certs"
fi
echo "# switching the Auto-Unlock ON"
# setting value in raspi blitz config

View file

@ -3,7 +3,7 @@
# command info
if [ "$1" = "-h" ] || [ "$1" = "-help" ]; then
echo "tool to reset or sync credentials (e.g. macaroons)"
echo "lnd.credentials.sh [reset|sync]"
echo "lnd.credentials.sh [reset|sync] [?tls|macaroons]"
exit 1
fi
@ -63,35 +63,64 @@ function copy_mac_set_perms() {
# RESET Macaroons and TLS
###########################
if [ "$1" = "reset" ]; then
clear
echo "###### RESET MACAROONS AND TLS.cert ######"
echo ""
echo "All your macaroons and the tls.cert get deleted and recreated."
echo "Use this to invalidate former EXPORTS for example if you loose a device."
echo ""
cd || exit
echo "- deleting old macaroons"
sudo find /mnt/hdd/app-data/lnd/data/chain/"${network}"/"${chain}"net/ -iname '*.macaroon' -delete
sudo find /home/bitcoin/.lnd/data/chain/"${network}"/"${chain}"net/ -iname '*.macaroon' -delete
sudo rm /home/bitcoin/.lnd/data/chain/"${network}"/"${chain}"net/macaroons.db
echo "- resetting TLS cert"
sudo /home/admin/config.scripts/lnd.newtlscert.sh
echo "- restarting LND ... wait 10 secs"
echo "### lnd.credentials.sh reset"
# default reset both
resetTLS=1
resetMacaroons=1
# optional second paramter to just reset one on them
if [ "$2" == "tls" ]; then
echo "# just resetting TLS"
resetTLS=1
resetMacaroons=0
fi
if [ "$2" == "macaroons" ]; then
echo "# just resetting Macaroons"
resetTLS=0
resetMacaroons=1
fi
if [ ${resetMacaroons} -eq 1 ]; then
echo "## Resetting Macaroons"
echo "# all your macaroons get deleted and recreated"
cd || exit
sudo find /mnt/hdd/app-data/lnd/data/chain/"${network}"/"${chain}"net/ -iname '*.macaroon' -delete
sudo find /home/bitcoin/.lnd/data/chain/"${network}"/"${chain}"net/ -iname '*.macaroon' -delete
sudo rm /home/bitcoin/.lnd/data/chain/"${network}"/"${chain}"net/macaroons.db
fi
if [ ${resetTLS} -eq 1 ]; then
echo "## Resetting TLS"
echo "# tls cert gets deleted and recreated"
cd || exit
sudo /home/admin/config.scripts/lnd.tlscert.sh refresh
fi
# unlock wallet after restart
echo "# restarting LND ... wait 10 secs"
sudo systemctl start lnd
sleep 10
sudo -u bitcoin lncli --chain="${network}" --network="${chain}"net unlock
echo "- creating new macaroons ... wait 10 secs"
# unlock wallet after restart
sudo /home/admin/config.scripts/lnd.unlock.sh
sleep 10
echo "- copy new macaroons to central app-data directory and ensure unix ownerships and permissions"
copy_mac_set_perms admin.macaroon lndadmin "${network}" "${chain}"
copy_mac_set_perms invoice.macaroon lndinvoice "${network}" "${chain}"
copy_mac_set_perms readonly.macaroon lndreadonly "${network}" "${chain}"
echo "OK DONE"
if [ ${resetMacaroons} -eq 1 ]; then
echo "# copy new macaroons to central app-data directory and ensure unix ownerships and permissions"
copy_mac_set_perms admin.macaroon lndadmin "${network}" "${chain}"
copy_mac_set_perms invoice.macaroon lndinvoice "${network}" "${chain}"
copy_mac_set_perms readonly.macaroon lndreadonly "${network}" "${chain}"
echo "# OK DONE"
fi
###########################
# SYNC
###########################
elif [ "$1" = "sync" ]; then
echo "###### SYNCING MACAROONS, RPC Password AND TLS Certificate ######"
echo "# make sure LND app-data directories exist"

View file

@ -1,39 +0,0 @@
#!/bin/bash
# stop services
echo "making sure services are not running"
sudo systemctl stop lnd 2>/dev/null
echo "keep old tls data as backup"
sudo mv /mnt/hdd/lnd/tls.cert /mnt/hdd/lnd/tls.cert.old
sudo mv /mnt/hdd/lnd/tls.key /mnt/hdd/lnd/tls.key.old
echo "let lnd generate new TLSCert"
sudo -u bitcoin /usr/local/bin/lnd &>/dev/null &
echo "wait until generated"
newCertExists=0
count=0
while [ ${newCertExists} -eq 0 ]
do
count=$(($count + 1))
echo "(${count}/60) check for cert"
if [ ${count} -gt 60 ]; then
echo "FAIL - was not able to generate new LND certs"
exit 1
fi
newCertExists=$(sudo ls /mnt/hdd/lnd/tls.cert 2>/dev/null | grep -c '.cert')
sleep 2
done
sudo killall /usr/local/bin/lnd
sudo chmod 664 /mnt/hdd/lnd/tls.cert
sudo chown bitcoin:bitcoin "/mnt/hdd/lnd/tls.cert"
echo "symlink new cert to lnd app-data directory"
if ! [[ -L "/mnt/hdd/app-data/lnd/tls.cert" ]]; then
sudo rm -rf "/mnt/hdd/app-data/lnd/tls.cert" # not a symlink.. delete it silently
sudo ln -s /mnt/hdd/lnd/tls.cert /home/admin/.lnd/tls.cert # and create symlink
fi
echo "OK TLS certs are fresh"
# ToDo(frennkie) why doesn't this start lnd again? - I assume as _background will start it anyway?!
# ToDo(frennkie) the way LND generates the x509 certificate is not ideal -
# it may be better to simply run openssl and create a cert with our settings...

View file

@ -58,7 +58,7 @@ if [ "${mode}" = "on" ]; then
md5HashAfter=$(sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf)
if [ "${md5HashAfter}" != "${md5HashBefore}" ]; then
echo "# lnd.conf changed - TLS certs need refreshing"
sudo /home/admin/config.scripts/lnd.newtlscert.sh
sudo /home/admin/config.scripts/lnd.tlscert.sh refresh
else
echo "# lnd.conf NOT changed - keep TLS certs"
fi
@ -86,7 +86,7 @@ if [ "${mode}" = "off" ]; then
md5HashAfter=$(sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf)
if [ "${md5HashAfter}" != "${md5HashBefore}" ]; then
echo "# lnd.conf changed - TLS certs need refreshing"
sudo /home/admin/config.scripts/lnd.newtlscert.sh
sudo /home/admin/config.scripts/lnd.tlscert.sh refresh
else
echo "# lnd.conf NOT changed - keep TLS certs"
fi

View file

@ -4,7 +4,7 @@
# based on: https://github.com/rootzoll/raspiblitz/issues/386
if [ $# -eq 0 ]; then
echo "small config script set the port LND is running on"
echo "script set the port LND is running on"
echo "lnd.setport.sh [portnumber]"
exit 1
fi

View file

@ -0,0 +1,123 @@
#!/bin/bash
# ToDo(frennkie) why doesn't this start lnd again? - I assume as _background will start it anyway?!
# ToDo(frennkie) the way LND generates the x509 certificate is not ideal -
# it may be better to simply run openssl and create a cert with our settings...
if [ $# -eq 0 ]; then
echo "script to set and config TLS Cert for LND"
echo "lnd.tlscert.sh refresh"
echo "lnd.tlscert.sh ip-add [ip]"
echo "lnd.tlscert.sh ip-remove [ip]"
exit 1
fi
TLSPATH="/mnt/hdd/lnd"
LNDCONF="/mnt/hdd/lnd/lnd.conf"
### ADD IP
if [ "$1" = "ip-add" ]; then
# 2. parameter: ip
ip=$2
countDots=$(echo "$ip" | grep -c '.')
if [ ${countDots} -eq 0 ]; then
echo "error='missing or invalid IP'"
exit
fi
# check if IP is already added
found=$(sudo cat ${LNDCONF} | grep -c "tlsextraip=${ip}")
if [ ${found} -gt 0 ]; then
echo "# OK the IP was already added lnd.conf"
exit
fi
# simply add the line to the LND conf
sudo sed -i "10itlsextraip=${ip}" ${LNDCONF}
# check if line is added
found=$(sudo cat ${LNDCONF} | grep -c "tlsextraip=${ip}")
if [ ${found} -eq 0 ]; then
echo "error='failed adding IP'"
exit
fi
echo "# OK added IP to lnd.conf - refresh of TLS cert is needed"
exit
fi
### REMOVE IP
if [ "$1" = "ip-remove" ]; then
# 2. parameter: ip
ip=$2
countDots=$(echo "$ip" | grep -c '.')
if [ ${countDots} -eq 0 ]; then
echo "error='missing or invalid IP'"
exit
fi
# remove the line to the LND conf
sudo sed -i "/tlsextraip=${ip}/d" ${LNDCONF}
# check if line is removed
found=$(sudo cat ${LNDCONF} | grep -c "tlsextraip=${ip}")
if [ ${found} -gt 0 ]; then
echo "error='failed removing IP'"
exit
fi
echo "# OK removed IP from lnd.conf - refresh of TLS cert is needed"
exit
fi
### REFRESH
if [ "$1" = "refresh" ]; then
echo "# making sure services are not running"
sudo systemctl stop lnd 2>/dev/null
echo "# keep old tls data as backup"
sudo rm ${TLSPATH}/tls.cert.old 2>/dev/null
sudo rm ${TLSPATH}/tls.key.old 2>/dev/null
sudo mv ${TLSPATH}/tls.cert ${TLSPATH}/tls.cert.old
sudo mv ${TLSPATH}/tls.key ${TLSPATH}/tls.key.old
echo "# start to create new generate new TLSCert"
sudo systemctl start lnd
echo "# wait until generated"
newCertExists=0
count=0
while [ ${newCertExists} -eq 0 ]
do
count=$(($count + 1))
echo "# (${count}/60) check for cert"
if [ ${count} -gt 60 ]; then
sudo systemctl stop lnd
echo "error='failed to generate new LND cert'"
exit 1
fi
newCertExists=$(sudo ls /mnt/hdd/lnd/tls.cert 2>/dev/null | grep -c '.cert')
sleep 2
done
# stop lnd and let outside decide to restart or not
sudo systemctl stop lnd
sudo chmod 664 ${TLSPATH}/tls.cert
sudo chown bitcoin:bitcoin "/mnt/hdd/lnd/tls.cert"
echo "# symlink new cert to lnd app-data directory"
if ! [[ -L "/mnt/hdd/app-data/lnd/tls.cert" ]]; then
sudo rm -rf "/mnt/hdd/app-data/lnd/tls.cert" # not a symlink.. delete it silently
sudo ln -s ${TLSPATH}/tls.cert /home/admin/.lnd/tls.cert # and create symlink
fi
echo "# OK TLS certs are fresh - start of LND service needed"
exit
fi

View file

@ -1,29 +0,0 @@
# parameter #1: password c to unlock wallet
import base64
import codecs
import json
import requests
import sys
pw = sys.argv[1]
url = 'https://localhost:8080/v1/unlockwallet'
cert_path = '/mnt/hdd/lnd/tls.cert'
try:
pw_b64 = base64.b64encode(pw).decode()
except TypeError: # for Python3+
pw_b64 = base64.b64encode(pw.encode()).decode('UTF-8')
data = {'wallet_password': pw_b64}
try:
r = requests.post(url, verify=cert_path, data=json.dumps(data))
except requests.exceptions.ConnectionError as err:
print(err)
print("\nAn Error occurred - is LND running?")
sys.exit(1)
if r.status_code == 404:
print("Already unlocked!")
else:
print(r.json())

View file

@ -0,0 +1,126 @@
#!/bin/bash
if [ "$1" == "-h" ] || [ "$1" == "help" ]; then
echo "script to unlock LND wallet"
echo "lnd.unlock.sh [?passwordC]"
exit 1
fi
# 1. parameter
passwordC="$1"
# check if wallet is already unlocked
echo "# checking LND wallet ... (can take some time)"
walletLocked=$(sudo -u bitcoin /usr/local/bin/lncli getinfo 2>&1 | grep -c unlock)
if [ ${walletLocked} -eq 0 ]; then
echo "# OK LND wallet was already unlocked"
exit 0
fi
# check if LND is below 0.10 (has no STDIN password option)
fallback=0
source <(/home/admin/config.scripts/lnd.update.sh info)
if [ ${lndInstalledVersionMajor} -eq 0 ] && [ ${lndInstalledVersionMain} -lt 10 ]; then
if [ ${#passwordC} -gt 0 ]; then
echo "error='lnd version too old'"
exit 1
else
fallback=1
fi
fi
# if no password check if stored for auto-unlock
if [ ${#passwordC} -eq 0 ]; then
autoUnlockExists=$(sudo ls /root/lnd.autounlock.pwd 2>/dev/null | grep -c "lnd.autounlock.pwd")
if [ ${autoUnlockExists} -eq 1 ]; then
echo "# using auto-unlock"
passwordC=$(sudo cat /root/lnd.autounlock.pwd)
fi
fi
# if still no password get from user
manualEntry=0
if [ ${#passwordC} -eq 0 ] && [ ${fallback} -eq 0 ]; then
echo "# manual input"
manualEntry=1
passwordC=$(whiptail --passwordbox "\nEnter Password C to unlock wallet:\n" 9 52 "" --title " LND Wallet " --backtitle "RaspiBlitz" 3>&1 1>&2 2>&3)
fi
loopCount=0
while [ ${fallback} -eq 0 ]
do
# TRY TO UNLOCK ...
loopCount=$(($loopCount +1))
echo "# calling: lncli unlock"
result=$(echo "$passwordC" | sudo -u bitcoin lncli unlock --recovery_window=5000 --stdin 2>&1)
wasUnlocked=$(echo "${result}" | grep -c 'successfully unlocked')
wrongPassword=$(echo "${result}" | grep -c 'invalid passphrase')
if [ ${wasUnlocked} -gt 0 ]; then
# SUCCESS UNLOCK
echo "# OK LND wallet unlocked"
exit 0
elif [ ${wrongPassword} -gt 0 ]; then
# WRONG PASSWORD
echo "# wrong password"
if [ ${manualEntry} -eq 1 ]; then
passwordC=$(whiptail --passwordbox "\nEnter Password C again:\n" 9 52 "" --title " Password was Wrong " --backtitle "RaspiBlitz - LND Wallet" 3>&1 1>&2 2>&3)
else
echo "error='wrong password'"
exit 1
fi
else
# UNKOWN RESULT
# check if wallet was unlocked anyway
walletLocked=$(sudo -u bitcoin /usr/local/bin/lncli getinfo 2>&1 | grep -c unlock)
if [ ${walletUnlocked} -eq 0 ]; then
echo "# OK LND wallet unlocked"
exit 0
fi
echo "# unkown error"
if [ ${manualEntry} -eq 1 ]; then
whiptail --title " LND ERROR " --msgbox "${result}" --ok-button "Try CLI" 8 60
fallback=1
else
# maybe lncli is waiting to get ready (wait and loop)
if [ ${loopCount} -gt 10 ]; then
echo "error='failed to unlock'"
exit 1
fi
sleep 2
fi
fi
done
# FALBACK LND CLI UNLOCK
walletLocked=1
while [ ${walletLocked} -gt 0 ]
do
# do CLI unlock
echo
echo "############################"
echo "Calling: lncli unlock"
echo "Please re-enter Password C:"
lncli unlock --recovery_window=5000
# test unlock
walletLocked=$(sudo -u bitcoin /usr/local/bin/lncli getinfo 2>&1 | grep -c unlock)
if [ ${walletLocked} -eq 0 ]; then
echo "# --> OK LND wallet unlocked"
else
echo "# --> Was not able to unlock wallet ... try again or use CTRL-C to exit"
fi
done

View file

@ -143,7 +143,7 @@ if [ "${mode}" = "verified" ]; then
echo
echo "# check binary was not manipulated (checksum test)"
sudo -u admin wget -N https://github.com/lightningnetwork/lnd/releases/download/v${lndUpdateVersion}/manifest-v${lndUpdateVersion}.txt.sig
sudo -u admin wget -N -O "${downloadDir}/pgp_keys.asc" ${lndUpdatePGPpkeys}
sudo -u admin wget --no-check-certificate -N -O "${downloadDir}/pgp_keys.asc" ${lndUpdatePGPpkeys}
binaryChecksum=$(sha256sum ${binaryName} | cut -d " " -f1)
if [ "${binaryChecksum}" != "${lndSHA256}" ]; then
echo "error='checksum not matching'"