Created
December 6, 2019 15:38
-
-
Save dennisreimann/c2a6670df504c291728d56597a2ab6f2 to your computer and use it in GitHub Desktop.
BTC/LND Status Shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# by dennisreimann | |
# most of this is taken from Stadicus: | |
# https://stadicus.github.io/RaspiBolt/raspibolt_61_system-overview.html | |
# set colors | |
color_red='\033[0;31m' | |
color_green='\033[0;32m' | |
color_yellow='\033[0;33m' | |
color_blue='\033[0;34m' | |
color_cyan='\033[0;36m' | |
color_gray='\033[0;37m' | |
color_purple='\033[0;35m' | |
# set datadir | |
bitcoin_dir="/home/bitcoin/.bitcoin" | |
lnd_dir="/home/bitcoin/.lnd" | |
# Set to mount point of blockchain volume. This is used to calculate USB HDD usage % | |
ext_hdd="/mnt/hdd" | |
# Set to network device name (usually eth0 for ethernet or wlan0 for wireless on raspberry pi unless you have 'Predictable Network Names' turned on in raspi-config. To get network device name run ifconfig.) | |
network_name="eth0" | |
# get uptime & load | |
load=$(w | grep "load average:" | cut -c11-) | |
# get CPU temp | |
cpu=$(cat /sys/class/thermal/thermal_zone0/temp) | |
temp=$((cpu/1000)) | |
# get memory | |
ram_avail=$(free -m | grep Mem | awk '{ print $7 }') | |
ram=$(printf "%sM / %sM" "${ram_avail}" "$(free -m | grep Mem | awk '{ print $2 }')") | |
if [ ${ram_avail} -lt 100 ]; then | |
color_ram="${color_red}\e[7m" | |
else | |
color_ram=${color_green} | |
fi | |
# get storage | |
sd_free_ratio=$(printf "%d" "$(df | grep "/$" | awk '{ print $4/$2*100 }')") 2>/dev/null | |
sd=$(printf "%s (%s%%)" "$(df -h | grep '/$' | awk '{ print $4 }')" "${sd_free_ratio}") | |
if [ ${sd_free_ratio} -lt 10 ]; then | |
color_sd="${color_red}" | |
else | |
color_sd=${color_green} | |
fi | |
hdd_free_ratio=$(printf "%d" "$(df | grep ${ext_hdd} | awk '{ print $4/$2*100 }')") 2>/dev/null | |
hdd=$(printf "%s (%s%%)" "$(df -h | grep ${ext_hdd} | awk '{ print $4 }')" "${hdd_free_ratio}") | |
if [ ${hdd_free_ratio} -lt 10 ]; then | |
color_hdd="${color_red}\e[7m" | |
else | |
color_hdd=${color_green} | |
fi | |
# get network traffic | |
network_rx=$(ifconfig ${network_name} | grep 'RX packets' | awk '{ print $6$7 }' | sed 's/[()]//g') | |
network_tx=$(ifconfig ${network_name} | grep 'TX packets' | awk '{ print $6$7 }' | sed 's/[()]//g') | |
# Bitcoin blockchain | |
btc_path=$(command -v bitcoin-cli) | |
if [ -n "${btc_path}" ]; then | |
chain="$(bitcoin-cli -datadir=${bitcoin_dir} getblockchaininfo | jq -r '.chain')" | |
if [ -n "$chain" ]; then | |
# get sync status | |
block_chain="$(bitcoin-cli -datadir=${bitcoin_dir} getblockcount)" | |
block_verified="$(bitcoin-cli -datadir=${bitcoin_dir} getblockchaininfo | jq -r '.blocks')" | |
block_diff=$(expr ${block_chain} - ${block_verified}) | |
progress="$(bitcoin-cli -datadir=${bitcoin_dir} getblockchaininfo | jq -r '.verificationprogress')" | |
sync_percentage=$(printf "%.2f%%" "$(echo $progress | awk '{print 100 * $1}')") | |
if [ ${block_diff} -eq 0 ]; then # fully synced | |
sync="OK" | |
sync_color="${color_green}" | |
elif [ ${block_diff} -eq 1 ]; then # fully synced | |
sync="1 block behind" | |
sync_color="${color_green}" | |
elif [ ${block_diff} -le 10 ]; then # <= 2 blocks behind | |
sync="${block_diff} blocks behind" | |
sync_color="${color_amber}" | |
else | |
sync="In progress: ${sync_percentage}" | |
sync_color="${color_red}" | |
fi | |
# get last known block | |
last_block="$(bitcoin-cli -datadir=${bitcoin_dir} getblockcount)" | |
if [ ! -z "${last_block}" ]; then | |
btc_line2="${btc_line2} ${color_gray}(block ${last_block})" | |
fi | |
# get mem pool transactions | |
mempool="$(bitcoin-cli -datadir=${bitcoin_dir} getmempoolinfo | jq -r '.size')" | |
# TOR or IP | |
networkInfo=$(bitcoin-cli -datadir=${bitcoin_dir} getnetworkinfo) | |
onion=$(echo ${networkInfo} | jq -r '.localaddresses [0] .address') | |
# get connection info | |
connections="$(echo ${networkInfo} | jq .connections)" | |
inbound="$(bitcoin-cli -datadir=${bitcoin_dir} getpeerinfo | jq '.[] | select(.inbound == true)' | jq -s 'length')" | |
outbound="$(bitcoin-cli -datadir=${bitcoin_dir} getpeerinfo | jq '.[] | select(.inbound == false)' | jq -s 'length')" | |
else | |
btc_line2="${color_red}NOT RUNNING\t\t" | |
fi | |
fi | |
# get public IP address & port | |
public_ip=$(curl -s https://api.ipify.org) | |
public_port=$(cat ${bitcoin_dir}/bitcoin.conf 2>/dev/null | grep ^port= | awk -F"=" '{print $2}') | |
if [ "${public_port}" = "" ]; then | |
if [ $chain = "test" ]; then | |
public_port=18333 | |
else | |
public_port=8333 | |
fi | |
fi | |
public_check=$(timeout 2s nc -z ${public_ip} ${public_port}; echo $?) | |
if [ $public_check = "0" ]; then | |
public="Yes" | |
public_color="${color_green}" | |
else | |
public="Not reachable" | |
public_color="${color_red}" | |
fi | |
public_addr="${public_ip}:${public_port}" | |
onion_addr="${onion}:${public_port}" | |
# get LND info | |
if [ $chain = "test" ]; then | |
macaroon_path="${lnd_dir}/data/chain/bitcoin/testnet/readonly.macaroon" | |
else | |
macaroon_path="${lnd_dir}/data/chain/bitcoin/mainnet/readonly.macaroon" | |
fi | |
lncli="/usr/local/bin/lncli --macaroonpath=${macaroon_path} --tlscertpath=${lnd_dir}/tls.cert" | |
$lncli getinfo 2>&1 | grep "Please unlock" >/dev/null | |
wallet_unlocked=$? | |
if [ "$wallet_unlocked" -eq 0 ] ; then | |
alias_color="${color_red}" | |
ln_alias="Wallet Locked" | |
else | |
alias_color="${color_grey}" | |
ln_alias="$($lncli getinfo | jq -r '.alias')" 2>/dev/null | |
ln_walletbalance="$($lncli walletbalance | jq -r '.confirmed_balance')" 2>/dev/null | |
ln_channelbalance="$($lncli channelbalance | jq -r '.balance')" 2>/dev/null | |
ln_peers="$($lncli getinfo | jq -r '.num_peers')" 2>/dev/null | |
ln_channels_online="$($lncli getinfo | jq -r '.num_active_channels')" 2>/dev/null | |
ln_channels_total="$($lncli listchannels | jq '.[] | length')" 2>/dev/null | |
ln_external="$($lncli getinfo | jq -r '.uris[0]' | tr "@" " " | awk '{ print $2 }')" 2>/dev/null | |
ln_external_ip="$(echo $ln_external | tr ":" " " | awk '{ print $1 }' )" 2>/dev/null | |
if [ "$ln_external_ip" = "$public_ip" ]; then | |
external_color="${color_grey}" | |
else | |
external_color="${color_red}" | |
fi | |
ln_pendingopen=$($lncli pendingchannels | jq '.pending_open_channels[].channel.local_balance|tonumber ' | awk '{sum+=$0} END{print sum}') | |
if [ -z $ln_pendingopen ]; then | |
ln_pendingopen=0 | |
fi | |
ln_pendingforce=$($lncli pendingchannels | jq '.pending_force_closing_channels[].channel.local_balance|tonumber ' | awk '{sum+=$0} END{print sum}') | |
if [ -z $ln_pendingforce ]; then | |
ln_pendingforce=0 | |
fi | |
ln_waitingclose=$($lncli pendingchannels | jq '.waiting_close_channels[].channel.local_balance|tonumber ' | awk '{sum+=$0} END{print sum}') | |
if [ -z $ln_waitingclose ]; then | |
ln_waitingclose=0 | |
fi | |
ln_pendinglocal=$(expr $ln_pendingopen + $ln_pendingforce + $ln_pendingclose + $ln_waitingclose) | |
fi | |
sum_balance=0 | |
if [ ! -z "$ln_channelbalance" ]; then | |
sum_balance=$(expr $ln_channelbalance + $sum_balance ) | |
fi | |
if [ ! -z "$ln_walletbalance" ]; then | |
sum_balance=$(expr $ln_walletbalance + $sum_balance ) | |
fi | |
if [ ! -z "$ln_pendinglocal" ]; then | |
sum_balance=$(expr $sum_balance + $ln_pendinglocal ) | |
fi | |
printf " | |
${color_yellow} _____________ | |
${color_yellow} /###########/ ${color_yellow}Blitzbank Here's to the reckless! | |
${color_yellow} /##########/ ${color_yellow}---------------------------------------------------------------------------------- | |
${color_yellow} /#########/ ${color_gray}BTC: ${color_purple}${onion_addr} ${color_gray}Public: ${public_addr} ${public_color}${public} | |
${color_yellow} /########/ ${color_gray}LND: ${color_purple}${ln_external} | |
${color_yellow} /#######/ ${color_yellow}---------------------------------------------------------------------------------- | |
${color_yellow} /######/ ${color_gray}${load} - CPU Temp ${temp}°C | |
${color_yellow} /#####/__________ | |
${color_yellow} /###############/ ${color_yellow}%-28s %-28s %-28s | |
${color_yellow} /######/ ${color_gray}Memory ${color_ram}%-20s${color_gray}Sync ${sync_color}%-18s${color_gray} ${alias_color}%s | |
${color_yellow} /#####/ ${color_gray}SSD ${color_sd}%-20s${color_gray}Mempool %-19s${color_gray}%s/%s Channels | |
${color_yellow} /####/ ${color_gray}HDD ${color_hdd}%-20s${color_gray}Peers In/Out: %-11s${color_gray}%s peers | |
${color_yellow} /###/ ${color_gray} | |
${color_yellow} /##/ ${color_gray}Traffic ▲ %-44s ${color_gray}Onchain: ${color_cyan}%10s sats | |
${color_yellow} /#/ ${color_gray} ▼ %-44s ${color_gray}Lightning: ${color_cyan}%10s sats | |
${color_yellow} // ${color_gray} %-44s ${color_gray}Pending: ${color_cyan}%10s sats | |
${color_yellow} / ${color_gray} %-44s ${color_gray}Total: ${color_cyan}%10s sats | |
${color_yellow} ${color_yellow}---------------------------------------------------------------------------------- | |
%s | |
" \ | |
"Resources free" "฿itcoin (${chain}net)" "Lightning (LND)" \ | |
"${ram}" "${sync}" "${ln_alias}" \ | |
"${sd}" "${mempool} tx" "${ln_channels_online}" "${ln_channels_total}" \ | |
"${hdd}" "${inbound}/${outbound}" "${ln_peers}" \ | |
"${network_tx}" "${ln_walletbalance}" \ | |
"${network_rx}" "${ln_channelbalance}" \ | |
"" "$ln_pendinglocal" \ | |
"" "$sum_balance" \ | |
"" | |
echo "$(tput -T xterm sgr0)" |
Author
dennisreimann
commented
Dec 6, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment