Skip to content

Instantly share code, notes, and snippets.

@dennisreimann
Created December 6, 2019 15:38
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dennisreimann/c2a6670df504c291728d56597a2ab6f2 to your computer and use it in GitHub Desktop.
Save dennisreimann/c2a6670df504c291728d56597a2ab6f2 to your computer and use it in GitHub Desktop.
BTC/LND Status Shell
#!/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)"
@dennisreimann
Copy link
Author

blitzbank-status

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment