Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jorijn/7b41ec96da8fe2f684de68ec7b88ff40 to your computer and use it in GitHub Desktop.
Save jorijn/7b41ec96da8fe2f684de68ec7b88ff40 to your computer and use it in GitHub Desktop.
Bash lnd rebalance helper
#!/bin/bash
FAILFILE=./failcombinaties
# Clear out out lists
> /tmp/in
> /tmp/out
# Store invoices in an array for possible reuse
declare -a INVOICES
# List all active channels, and do some ugly formatting tricks
lncli listchannels --active_only --public_only |\
jq -c '.channels[] | [.chan_id,.remote_pubkey,((.local_balance|tonumber)/((.remote_balance|tonumber)+1)),(.capacity|tonumber)]'|\
sed 's/["\\[]//g' |\
cut -d ']' -f1 |\
sort -R |\
while read line; do
# Going through all channels, building lists
CHANID=$(echo $line | cut -d, -f1)
KEY=$(echo $line | cut -d, -f2)
LOCAL=$(echo $line | cut -d, -f3)
TOTAL=$(echo $line | cut -d, -f4)
# Determine here what channels should go on what list
if [[ $LOCAL < 0.3 ]]; then
# This channel has a low percentage on local side
echo "$line" >> /tmp/in
fi
if [[ $LOCAL > 3 ]]; then
# This channel has a high percentage on local side
echo "$line" >> /tmp/out
fi
done
# Now we will go through our lists and match them all up
PREVAMOUNT=0
while read in; do
# Getting lines where we have a LOW local percentage
CHANin=$(echo $in | cut -d, -f1)
KEYin=$(echo $in | cut -d, -f2)
LOCALin=$(echo $in | cut -d, -f3)
TOTALin=$(echo $in | cut -d, -f4)
# Match each IN with an OUT
while read out; do
CHANout=$(echo $out | cut -d, -f1)
KEYout=$(echo $out | cut -d, -f2)
LOCALout=$(echo $out | cut -d, -f3)
TOTALout=$(echo $out | cut -d, -f4)
echo
echo "Now considering OUT $KEYout $CHANout $TOTALout"
echo "Now considering IN $KEYin $CHANin $TOTALin"
# Use smaller side
if [[ $TOTALout < $TOTALin ]]; then
AMOUNT=$(( $TOTALout / 3 ))
else
AMOUNT=$(( $TOTALin / 3 ))
fi
# Cap at 250k sat
echo "Calculated amount $AMOUNT"
if [[ $AMOUNT > 100000 ]]; then
AMOUNT=250000
fi
# Set a max fee
MAXFEE=$(( $AMOUNT / 3000 ))
# See if this failed before
if grep -q "$CHANout $KEYin" $FAILFILE; then
echo "This failed before
continue"
fi
# Invoice for amount
if [[ -z ${INVOICES[$AMOUNT]} ]]; then
# We have not such an inv yet
INV=$( lncli addinvoice --amt $AMOUNT | jq -r .payment_request )
INVOICES[$AMOUNT]=$INV
else
INV=${INVOICES[$AMOUNT]}
fi
# The actual payment. Let LND do the heavy lifting here!!
CMD="lncli payinvoice --force --allow_self_payment --outgoing_chan_id $CHANout --last_hop $KEYin --fee_limit $MAXFEE $INV"
echo $CMD \# $AMOUNT sat total
$CMD
if [[ $? == 0 ]]; then
echo "Payment succesful"
exit 0
# We quit. Start the script again. Our lists are now useless.
fi
# Not succesful, ban!
echo "$CHANout $KEYin" >> $FAILFILE
#sleep 0.5
PREVAMOUNT=$AMOUNT
done </tmp/out
done < /tmp/in
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment