#!/bin/bash #This is a script to install LND. #Global Functions. #Global Functions. is_package_installed() { if dpkg -l "$1" 2>/dev/null | grep -q "^ii"; then echo "$1 is installed." return 0 # Package is installed else echo "$1 is not installed." return 1 # Package is not installed fi } prompt_yes_no() { local question="$1" local default_choice="${2:-yes}" while true; do read -p "$question (y/n) [default: $default_choice]: " user_choice case $user_choice in [Yy]) echo "yes" return ;; [Nn]) echo "no" return ;; "") # If the user just presses Enter, return the default choice echo "$default_choice" return ;; *) echo "Invalid choice. Please enter 'y' for yes or 'n' for no." ;; esac done } is_bitcoin_core_installed() { command -v bitcoind &>/dev/null } # Lightning Stuff # Function to check if Go is installed and upgrade to the latest version if needed upgrade_go() { local installed_go_version=$(go version 2>/dev/null | grep -oP 'go[0-9.]+') local latest_go_version=$(curl -s https://golang.org/dl/ | grep -oP 'https://golang.org/dl/go([0-9.]+).linux-amd64.tar.gz' | head -1 | grep -oP 'go([0-9.]+)') if [[ -z "$installed_go_version" ]]; then echo "Go is not installed. Installing the latest version." elif [[ "$installed_go_version" == "$latest_go_version" ]]; then echo "Latest version of Go ($installed_go_version) is already installed. Skipping." return else echo "Upgrading Go from $installed_go_version to $latest_go_version." fi wget -q "https://golang.org/dl/$latest_go_version.linux-amd64.tar.gz" -P /tmp || { echo "Failed to download Go. Aborting." exit 1 } tar -C /usr/local -xzf "/tmp/$latest_go_version.linux-amd64.tar.gz" || { echo "Failed to extract Go. Aborting." exit 1 } rm "/tmp/$latest_go_version.linux-amd64.tar.gz" if ! grep -q '/usr/local/go/bin' /etc/profile; then echo "export PATH=\$PATH:/usr/local/go/bin" >>/etc/profile echo "Go installation/upgrade completed successfully! Sourcing /etc/profile to update the PATH for the current session." source /etc/profile else echo "Go installation/upgrade completed successfully!" fi } # Function to install LND install_lnd() { # Edit the bitcoin.conf file using cat bitcoin_conf_file="/home/bitcoin/.bitcoin/bitcoin.conf" if [ -f "$bitcoin_conf_file" ]; then echo "Editing the bitcoin.conf file..." cat <>"$bitcoin_conf_file" # [RPC] debug=rpc rpcauth='lnd:1628299163766bdce1b3b9d321955971\$dfeb5a806808e3f5f31b46bc8289c79f27f679cfd41b9df1e154ab6588e10ad7' # [zeromq] zmqpubrawblock=tcp://127.0.0.1:28332 zmqpubrawtx=tcp://127.0.0.1:28333 EOF else echo "Bitcoin configuration file not found at $bitcoin_conf_file. Please ensure Bitcoin Core is correctly configured." fi # Restart bitcoind echo "Restarting bitcoind..." sudo systemctl restart bitcoind echo "bitcoind has been restarted." echo "Checking the latest release of LND..." latest_release=$(curl -s https://api.github.com/repos/lightningnetwork/lnd/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")') lnd_directory="/home/bitcoin/node/lnd" if [ -d "$lnd_directory" ]; then echo "LND directory already exists. Skipping cloning." else echo "Cloning LND into /home/bitcoin/node/lnd..." git clone https://github.com/lightningnetwork/lnd "$lnd_directory" fi cd "$lnd_directory" echo "Checking out the latest release of LND (v$latest_release)..." git checkout "v$latest_release" echo "Building and installing LND..." make install echo "LND has been installed successfully." # Move lncli binary to /usr/local/bin for system-wide access echo "Moving lncli binary to /usr/local/bin..." sudo mv /home/bitcoin/go/bin/lncli /usr/local/bin/ } # Function to configure LND and create its data folder configure_lnd() { echo "Configuring LND..." # Ask the user for their node name echo -n "Enter a name for your node: " read -r node_name # Create the LND data folder if it doesn't exist lnd_data_folder="/home/bitcoin/.lnd" mkdir -p "$lnd_data_folder" chown bitcoin:bitcoin "$lnd_data_folder" echo "LND data folder created: $lnd_data_folder" # Generate LND configuration file lnd_config_file="/home/bitcoin/.lnd/lnd.conf" cat <"$lnd_config_file" [Application Options] # Allow push payments accept-keysend=1 # Public network name (User-provided node name) alias=$node_name # Allow gift routes allow-circular-route=1 # Reduce the cooperative close chain fee coop-close-target-confs=1000 # Log levels debuglevel=CNCT=debug,CRTR=debug,HSWC=debug,NTFN=debug,RPCS=debug # Mark unpayable, unpaid invoices as deleted gc-canceled-invoices-on-startup=1 gc-canceled-invoices-on-the-fly=1 # Avoid historical graph data sync ignore-historical-gossip-filters=1 # Listen (not using Tor? Remove this) listen=localhost # Set the maximum amount of commit fees in a channel max-channel-fee-allocation=1.0 # Set the max timeout blocks of a payment max-cltv-expiry=5000 # Allow commitment fee to rise on anchor channels max-commit-fee-rate-anchors=100 # Pending channel limit maxpendingchannels=10 # Min inbound channel limit minchansize=5000 # gRPC socket binding rpclisten=0.0.0.0:10009 restlisten=0.0.0.0:8080 # Avoid high startup overhead stagger-initial-reconnect=1 # Delete and recreate RPC TLS certificate when details change or cert expires tlsautorefresh=true # Do not include IPs in the RPC TLS certificate tlsdisableautofill=true [Bitcoin] # Turn on Bitcoin mode bitcoin.active=1 # Set the channel confs to wait for channels bitcoin.defaultchanconfs=2 # Forward fee rate in parts per million bitcoin.feerate=1000 # Set bitcoin.testnet=1 or bitcoin.mainnet=1 as appropriate bitcoin.mainnet=1 # Set the lower bound for HTLCs bitcoin.minhtlc=1 # Set backing node, bitcoin.node=neutrino or bitcoin.node=bitcoind bitcoin.node=bitcoind # Set CLTV forwarding delta time bitcoin.timelockdelta=144 [bitcoind] # Configuration for using Bitcoin Core backend # Set the password to what the auth script said bitcoind.rpcpass=K@iHa$$0 # Set the username bitcoind.rpcuser=lnd # Set the ZMQ listeners bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 [bolt] # Enable database compaction when restarting db.bolt.auto-compact=true [protocol] # Enable large channels support protocol.wumbo-channels=1 [routerrpc] # Set minimum desired savings of trying a cheaper path routerrpc.attemptcost=10 routerrpc.attemptcostppm=10 # Set the number of historical routing records routerrpc.maxmchistory=10000 # Set the min confidence in a path worth trying routerrpc.minrtprob=0.005 [routing] # Remove channels from graph that have one side that hasn't made announcements routing.strictgraphpruning=1 EOF chown bitcoin:bitcoin "$lnd_config_file" echo "LND configuration file created: $lnd_config_file" # Ask the user about Tor mode and validate input while true; do read -rp "Do you want to use Tor only mode or hybrid mode? (Type 'yes' for Tor only mode, 'no' for hybrid mode): " tor_mode case $tor_mode in [Yy]es) echo "Enabling Tor mode in LND..." ;; [Nn]o) echo "LND will be configured in hybrid mode (without Tor)." ;; *) echo "Invalid input. Please type 'yes' for Tor only mode or 'no' for hybrid mode." continue ;; esac break done if [[ "$tor_mode" == "yes" ]]; then echo -n "Enter a password for LND Tor (this will be used to generate HashedControlPassword in torrc): " read -r tor_password # Set Tor configurations in LND conf file for Tor only mode cat <>"$lnd_config_file" [tor] tor.active=1 tor.v3=1 tor.socks=127.0.0.1:9050 tor.streamisolation=true tor.password=$tor_password tor.privatekeypath=/root/.lnd/v3_onion_private_key EOF # Update the torrc file with HashedControlPassword tor_hashed_password=$(tor --hash-password "$tor_password") echo "Updating torrc file with HashedControlPassword..." echo "HashedControlPassword $tor_hashed_password" | sudo tee -a /etc/tor/torrc sudo systemctl restart tor echo "LND has been configured in Tor only mode." else echo -n "Enter a password for LND Tor (this will be used to generate HashedControlPassword in torrc): " read -r tor_password # Set Tor configurations in LND conf file for hybrid mode cat <>"$lnd_config_file" [tor] tor.active=1 tor.v3=1 tor.socks=127.0.0.1:9050 tor.streamisolation=false tor.password=$tor_password tor.privatekeypath=/root/.lnd/v3_onion_private_key EOF # Update the torrc file with HashedControlPassword tor_hashed_password=$(tor --hash-password "$tor_password") echo "Updating torrc file with HashedControlPassword..." echo "HashedControlPassword $tor_hashed_password" | sudo tee -a /etc/tor/torrc sudo systemctl restart tor fi # Create the systemd service file for LND lnd_service_file="/etc/systemd/system/lnd.service" cat <"$wallet_password_file" chown bitcoin:bitcoin "$wallet_password_file" chmod 400 "$wallet_password_file" } # Ride the lightning dashboard stuff # Install RTL dash (Ride The Lightning) install_rtl() { echo "Checking for NPM (Node Package Manager)..." if ! command -v npm &>/dev/null; then echo "NPM not found. Installing NPM..." sleep 1 sudo apt update sudo apt install -qq -y npm else echo "NPM is already installed." sleep 1 fi rtl_folder="/home/bitcoin/node/RTL" echo "Cloning RTL into $rtl_folder..." git clone https://github.com/Ride-The-Lightning/RTL.git "$rtl_folder" echo "Entering the RTL folder..." cd "$rtl_folder" echo "Running npm install..." npm install --omit=dev echo "RTL has been installed successfully." sleep 1 } # Configure RTL and plug it into systemd configure_rtl() { echo "Configuring RTL..." sleep 1 # Get the computer's LAN IPv4 address lan_address=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1) # Ask the user about enabling FIAT conversion echo "Do you want to enable FIAT conversion? (Type 'yes' for enabling FIAT conversion, 'no' otherwise):" read -r enable_fiat rtl_folder="/home/bitcoin/node/RTL" rtl_config_file="$rtl_folder/RTL-Config.json" cat <"$rtl_config_file" { "multiPass": "password", "port": "3000", "defaultNodeIndex": 1, "dbDirectoryPath": "/home/bitcoin/node/RTL/data", "SSO": { "rtlSSO": 0 }, "nodes": [ { "index": 1, "lnNode": "LND", "lnImplementation": "LND", "Authentication": { "macaroonPath": "/home/bitcoin/.lnd/data/chain/bitcoin/mainnet" }, "Settings": { "userPersona": "OPERATOR", "themeMode": "NIGHT", "themeColor": "PURPLE", "channelBackupPath": "/home/bitcoin/bitcoin/node/RTL/backups", "bitcoindConfigPath": "/home/bitcoin/.bitcoin/bitcoin.conf", "logLevel": "INFO", "fiatConversion": "$enable_fiat", "unannouncedChannels": true, "lnServerUrl": "https://$lan_address:8080" } } ] } EOF echo "RTL configuration file created: $rtl_config_file" # Create the data folder for RTL rtl_data_folder="/home/bitcoin/node/RTL/data" mkdir -p "$rtl_data_folder" chown bitcoin:bitcoin "$rtl_data_folder" echo "RTL data folder created: $rtl_data_folder" echo "RTL has been configured." # Create and start the systemd service for RTL rtl_systemd_file="/etc/systemd/system/rtl.service" cat <"$rtl_systemd_file" [Unit] Description=Ride The Lightning (RTL) Bitcoin Lightning Network GUI After=bitcoind.service lnd.service [Service] User=bitcoin Group=bitcoin Type=simple ExecStart=/usr/bin/npm --prefix /home/bitcoin/node/RTL run start [Install] WantedBy=multi-user.target EOF echo "Systemd service file created: $rtl_systemd_file" sudo systemctl enable rtl sudo systemctl start rtl echo "RTL service has been started." echo "You can access RTL at http://localhost:8080 or http://$lan_address:8080" } # Root Check if [ "$EUID" -ne 0 ]; then echo "Please run this script as root." exit 1 fi # Welcom Message cat <<"EOF" ! .::::::. ... ::: .::.:::::::.. :::. :::. :::. :::. :::. ... :::::::-. .,:::::: ::::::::::. :::. .,-::::: ::: . ! ;;;` ` .;;;;;;;. ';;, ,;;;' ;;;;``;;;; ;;`;; `;;;;, `;;; `;;;;, `;;; .;;;;;;;. ;;, `';,;;;;'''' `;;;```.;;; ;;`;; ,;;;'````' ;;; .;;,. ! '[==/[[[[,,[[ \[[, \[[ .[[/ [[[,/[[[' ,[[ '[[, [[[[[. '[[ [[[[[. '[[,[[ \[[, `[[ [[ [[cccc `]]nnn]]' ,[[ '[[, [[[ [[[[[/' ! ''' $$$$, $$$ Y$c.$$" $$$$$$c c$$$cc$$$c $$$ "Y$c$$ $$$ "Y$c$$$$$, $$$ $$, $$ $$"""" $$$"" c$$$cc$$$c $$$ _$$$$, ! 88b dP"888,_ _,88P Y88P 888b "88bo, 888 888, 888 Y88 888 Y88"888,_ _,88P 888_,o8P' 888oo,__ 888o 888 888,`88bo,__,o, "888"88o, ! "YMmMY" "YMMMMMP" MP MMMM "W" YMM ""` MMM YM MMM YM "YMMMMMP" MMMMP"` """"YUMMM YMMMb YMM ""` "YUMMMMMP" MMM "MMP" EOF echo center_text "Thanks for using Enki's LND install script" center_text "This script will install LND and RTL on your box." center_text "To continue, hit any key." if [ -t 0 ]; then # Check if running in an interactive shell before using "read" center_text "To continue, hit any key." read -n 1 -s -r -p "" fi echo # Main part of the script. # Checks if Bitcoin Core is installed if is_bitcoin_core_installed; then echo "Core is installed. Lets " else echo "Bitcoin Core is not installed. do you want to install Core?" fi install_go # Install Go if it's not already installed install_lnd # Call the function to install LND configure_lnd # Call the function to configure LND and create its data folder prompt_create_wallet # Makes a wallet and adds the auto unlock file. install_rtl # Installs Ride The Lightning configure_rtl # makes the RTL config file and plugs it into systemd