Add files via upload

This commit is contained in:
curly60e 2022-03-15 21:23:22 -03:00 committed by GitHub
parent 5bc8014265
commit 962bb5d079
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 11627 additions and 0 deletions

File diff suppressed because it is too large Load diff

264
pybitblock/SPV/apisnd.py Normal file
View file

@ -0,0 +1,264 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
import os
import qrcode
import requests
import time as t
import sys
from nodeconnection import *
from pblogo import *
from logos import *
def clear(): # clear the screen
os.system('cls' if os.name=='nt' else 'clear')
def apisender():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
message = input("\nInsert your Message: ")
a = sys.getsizeof(message)
mini = 6000
n = (a * 50)
if n <= mini:
q = str(mini)
elif n >= mini:
k = n + mini
q = str(k)
url = 'https://api.blockstream.space/order'
sentby = " - PyBLOCK."
print("\n\tATENTION: YOU NEED TO PAY \033[1;31;40m" + q + "\033[0;37;40m MilliSats")
amountmsat = input("\nInsert the amount in MSats: ")
curl = 'curl -F ' "bid={} ".format(amountmsat) + '-F ' + ' "message=' + message + sentby + '" ' + url
sh = os.popen(curl)
clear()
blogo()
sh0 = sh.read()
while True:
if 'Bid too low' in sh0:
print("\n\t\033[1;31;40mATENTION: Per byte bid cannot be below 50 millisatoshis per byte.\033[0;37;40m\n")
print("Try again...\n")
message = input("\nInsert your Message: ")
a = sys.getsizeof(message)
mini = 6000
n = (a * 50)
if n <= mini:
q = str(mini)
elif n >= mini:
k = n + mini
q = str(k)
url = 'https://api.blockstream.space/order'
sentby = " - PyBLOCK."
print("\n\tATENTION: YOU NEED TO PAY \033[1;31;40m" + q + "\033[0;37;40m MilliSats")
amountmsat = input("\nInsert the amount in MSats: ")
curl = 'curl -F ' "bid={} ".format(amountmsat) + '-F ' + ' "message=' + message + sentby + '" ' + url
sh = os.popen(curl)
clear()
blogo()
sh0 = sh.read()
elif 'lightning_invoice' in sh0:
break
sh1 = str(sh0)
shh = sh1.split(',')
invoice = str(shh[6])
#---------------Token-----------
authtoken = str(shh[0])
authtoken1 = authtoken.split(':')
token = authtoken1[1]
#---------------End Token-------
#---------------Order-----------
uuid = str(shh[1])
uuid1 = uuid.split(':')
order = uuid1[1]
#---------------End Order-------
#---------------Amount----------
msat = str(shh[3])
msat1 = msat.split(':')
amount = msat1[1]
#---------------End Amount------
orderid = str(shh[1])
ln1 = invoice.split(':')
ln2 = str(ln1[1])
cln = ln2.strip('"')
print("\n\033[0;37;40mYour Token Authorization: \033[1;31;40m" + token + "\033[0;37;40m")
print("\033[0;37;40mYour Order Number: \033[1;31;40m" + order + "\033[0;37;40m")
print("\033[0;37;40mAmount in MSats: \033[1;33;40m" + amount + "\033[0;37;40m\n")
clear()
blogo()
node_not = input("Do you want to pay this message with your node? Y/n: ")
if node_not in ["Y", "y"]:
lndconnectload = {"ip_port":"", "tls":"", "macaroon":"", "ln":""}
lndconnectData = pickle.load(open("blndconnect.conf", "rb")) # Load the file 'bclock.conf'
lndconnectload = lndconnectData # Copy the variable pathv to 'path'
if lndconnectload['ip_port']:
print("\nInvoice: " + cln + "\n")
payinvoice()
elif lndconnectload['ln']:
print("\nInvoice: " + cln + "\n")
localpayinvoice()
elif node_not in ["N", "n"]:
print("\033[1;30;47m")
qr.add_data(cln)
qr.print_ascii()
print("\033[0;37;40m")
print("\nLND Invoice: " + cln + "\n")
sh.close()
continue1 = input("Continue? Y: ")
if continue1 == "Y" or continue1 == "y":
donate()
else:
t.sleep(2)
def apisenderFile():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
url = 'https://api.blockstream.space/order'
message = input("\nInsert the path to the File: ")
print("ATENTION: Minimum amount for sending a File is 50000 MSats")
amountmsat = input("\nInsert the amount in MSats: ")
curl = 'curl -F ' "bid={} ".format(amountmsat) + '-F ' + ' "file=@' + message + '" ' + url
sh = os.popen(curl)
sh0 = sh.read()
while True:
try:
if 'Bid too low' in sh0:
print("\n\t\033[1;31;40mATENTION: Per byte bid cannot be below 50 millisatoshis per byte.\033[0;37;40m\n")
print("Try again...\n")
url = 'https://api.blockstream.space/order'
message = input("\nInsert the path to the File: ")
print("ATENTION: Minimum amount for sending a File is 50000 MSats")
amountmsat = input("\nInsert the amount in MSats: ")
curl = 'curl -F ' "bid={} ".format(amountmsat) + '-F ' + ' "file=@' + message + '" ' + url
sh = os.popen(curl)
sh0 = sh.read()
elif 'lightning_invoice' in sh0:
break
except:
break
sh1 = str(sh0)
shh = sh1.split(',')
invoice = str(shh[6])
#---------------Token-----------
authtoken = str(shh[0])
authtoken1 = authtoken.split(':')
token = authtoken1[1]
#---------------End Token-------
#---------------Order-----------
uuid = str(shh[1])
uuid1 = uuid.split(':')
order = uuid1[1]
#---------------End Order-------
#---------------Amount----------
msat = str(shh[3])
msat1 = msat.split(':')
amount = msat1[1]
#---------------End Amount------
orderid = str(shh[1])
ln1 = invoice.split(':')
ln2 = str(ln1[1])
cln = ln2.strip('"')
print("\n\033[0;37;40mYour Token Authorization: \033[1;31;40m" + token + "\033[0;37;40m")
print("\033[0;37;40mYour Order Number: \033[1;31;40m" + order + "\033[0;37;40m")
print("\033[0;37;40mAmount in MSats: \033[1;33;40m" + amount + "\033[0;37;40m")
clear()
blogo()
try:
node_not = input("Do you want to pay this message with your node? Y/n: ")
if node_not in ["Y", "y"]:
lndconnectload = {"ip_port":"", "tls":"", "macaroon":"", "ln":""}
lndconnectData = pickle.load(open("blndconnect.conf", "rb")) # Load the file 'bclock.conf'
lndconnectload = lndconnectData # Copy the variable pathv to 'path'
if lndconnectload['ip_port']:
print("\nInvoice: " + cln + "\n")
payinvoice()
elif lndconnectload['ln']:
print("\nInvoice: " + cln + "\n")
localpayinvoice()
elif node_not in ["N", "n"]:
print("\033[1;30;47m")
qr.add_data(cln)
qr.print_ascii()
print("\033[0;37;40m")
print("\nLND Invoice: " + cln)
sh.close()
continue1 = input("Continue? Y: ")
if continue1 == "Y" or continue1 == "y":
donate()
else:
t.sleep(2)
except:
pass
def devAddr():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
print("\n\t\t\033[1;33;44mGive us some love and \033[1;31;44mDONATE\033[1;33;44m us! We will appreciate it. This will be a boost to continue this beautiful project! \033[0;37;40m")
url = 'https://api.tippin.me/v1/public/addinvoice/royalfield370'
response = requests.get(url)
responseB = str(response.text)
responseC = responseB
lnreq = responseC.split(',')
lnbc1 = lnreq[1]
lnbc1S = str(lnbc1)
lnbc1R = lnbc1S.split(':')
lnbc1W = lnbc1R[1]
ln = str(lnbc1W)
ln1 = ln.strip('"')
clear()
blogo()
try:
node_not = input("Do you want to pay this tip with your node? Y/n: ")
if node_not in ["Y", "y"]:
lndconnectload = {"ip_port":"", "tls":"", "macaroon":"", "ln":""}
lndconnectData = pickle.load(open("blndconnect.conf", "rb")) # Load the file 'bclock.conf'
lndconnectload = lndconnectData # Copy the variable pathv to 'path'
if lndconnectload['ip_port']:
print("\nInvoice: " + ln1 + "\n")
payinvoice()
elif lndconnectload['ln']:
print("\nInvoice: " + ln1 + "\n")
localpayinvoice()
elif node_not in ["N", "n"]:
print("\033[1;30;47m")
qr.add_data(ln1)
qr.print_ascii()
print("\033[0;37;40m")
print("LND Invoice: " + ln1)
response.close()
except:
pass
def donate():
print("""\t\t
\033[1;31;40mPyBLOCK\033[0;37;40m Menu
\033[1;32;40mA.\033[0;37;40m Donate
<<< Back Control + C
\n\n""")
menuB = (input("\033[1;32;40mSelect option: \033[0;37;40m"))
if menuB in ["A", "a"]:
devAddr()

BIN
pybitblock/SPV/bitcoin.pdf Normal file

Binary file not shown.

View file

@ -0,0 +1,153 @@
import pickle
import os
import sys
import base64, codecs, json, requests
from cfonts import render, say
def clear(): # clear the screen
os.system('cls' if os.name=='nt' else 'clear')
def rectangle(n):
x = n - 3
y = n - x
[
print(''.join(i))
for i in
(
''*x
if i in (0,y-1)
else
(
f'{""*n}{"|"*n}{""*n}'
if i >= (n+1)/2 and i <= (1*n)/2
else
f'\u001b[38;5;27m{""*(x-1)}'
)
for i in range(y)
)
]
def blogo():
if os.path.isfile('config/pyblocksettings.conf') or os.path.isfile('config/pyblocksettings.conf'): # Check if the file 'bclock.conf' is in the same folder
settingsv = pickle.load(open("config/pyblocksettings.conf", "rb")) # Load the file 'bclock.conf'
settings = settingsv # Copy the variable pathv to 'path'
else:
settings = {"gradient":"", "design":"block", "colorA":"green", "colorB":"yellow"}
pickle.dump(settings, open("config/pyblocksettings.conf", "wb"))
if settings["gradient"] == "grd":
output = render('PyBLOCK', gradient=[settings['colorA'], settings['colorB']], align='center', font=settings['design'])
else:
output = render('PyBLOCK', colors=[settings['colorA'], settings['colorB']], align='center', font=settings['design'])
print(output)
def artist(): # here we convert the result of the command 'getblockcount' on a random art design
while True:
try:
clear()
design()
except:
break
def design():
while True:
if os.path.isfile('config/pyblocksettingsClock.conf') or os.path.isfile('config/pyblocksettingsClock.conf'): # Check if the file 'bclock.conf' is in the same folder
settingsv = pickle.load(open("config/pyblocksettingsClock.conf", "rb")) # Load the file 'bclock.conf'
settingsClock = settingsv # Copy the variable pathv to 'path'
else:
settingsClock = {"gradient":"", "design":"block", "colorA":"green", "colorB":"yellow"}
pickle.dump(settingsClock, open("config/pyblocksettingsClock.conf", "wb"))
bitcoinclient = path['bitcoincli'] + " getblockcount"
block = os.popen(str(bitcoinclient)).read() # 'getblockcount' convert to string
b = block
a = b
blogo()
output = render(str(b), colors=[settingsClock['colorA'], settingsClock['colorB']], align='center')
print("\x1b[?25l" + output)
bitcoinclient = path['bitcoincli'] + " getbestblockhash"
bb = os.popen(str(bitcoinclient)).read()
ll = bb
bitcoinclientgetblock = path['bitcoincli'] + " getblock " + ll
qq = os.popen(bitcoinclientgetblock).read()
yy = json.loads(qq)
mm = yy
outputsize = render(str(mm['size']) + " bytes", colors=[settingsClock['colorA'], settingsClock['colorB']], align='center', font='tiny')
print("\x1b[?25l" + outputsize)
outputtxs = render(str(mm['nTx']) + " txs", colors=[settingsClock['colorA'], settingsClock['colorB']], align='center', font='tiny')
print("\x1b[?25l" + outputtxs)
sh = int(mm['nTx']) / 4
shq = int(sh)
ss = str(rectangle(shq))
print(ss.replace("None",""))
while True:
x = a
bitcoinclient = path['bitcoincli'] + " getblockcount"
block = os.popen(str(bitcoinclient)).read() # 'getblockcount' convert to string
b = block
if b > a:
clear()
blogo()
output = render(str(b), colors=[settingsClock['colorA'], settingsClock['colorB']], align='center')
print("\a\x1b[?25l" + output)
bitcoinclient = path['bitcoincli'] + " getbestblockhash"
bb = os.popen(str(bitcoinclient)).read()
ll = bb
bitcoinclientgetblock = path['bitcoincli'] + " getblock " + ll
qq = os.popen(bitcoinclientgetblock).read()
yy = json.loads(qq)
mm = yy
outputsize = render(str(mm['size']) + " bytes", colors=[settingsClock['colorA'], settingsClock['colorB']], align='center', font='tiny')
print("\x1b[?25l" + outputsize)
outputtxs = render(str(mm['nTx']) + " txs", colors=[settingsClock['colorA'], settingsClock['colorB']], align='center', font='tiny')
print("\x1b[?25l" + outputtxs)
sh = int(mm['nTx']) / 4
shq = int(sh)
ss = str(rectangle(shq))
print(ss.replace("None",""))
t.sleep(10)
txs = str(mm['nTx'])
if txs == "1":
try:
p = subprocess.Popen(['curl', 'https://poptart.spinda.net'])
p.wait(5)
except subprocess.TimeoutExpired:
p.kill()
print("\033[0;37;40m\x1b[?25l")
clear()
close()
a = b
output = render(str(b), colors=[settingsClock['colorA'], settingsClock['colorB']], align='center')
print("\x1b[?25l" + output)
settings = {"gradient":"", "design":"block", "colorA":"green", "colorB":"yellow"}
settingsClock = {"gradient":"", "colorA":"green", "colorB":"yellow"}
while True: # Loop
try:
clear()
path = {"ip_port":"", "rpcuser":"", "rpcpass":"", "bitcoincli":""}
if os.path.isfile('config/bclock.conf') or os.path.isfile('config/blnclock.conf'): # Check if the file 'bclock.conf' is in the same folder
pathv = pickle.load(open("config/bclock.conf", "rb")) # Load the file 'bclock.conf'
path = pathv # Copy the variable pathv to 'path'
else:
blogo()
print("Welcome to \033[1;31;40mPyBLOCK\033[0;37;40m\n\n")
print("\n\tIf you are going to use your local node leave IP:PORT/USER/PASSWORD in blank.\n")
path['ip_port'] = "http://{}".format(input("Insert IP:PORT to access your remote Bitcoin-Cli node: "))
path['rpcuser'] = input("RPC User: ")
path['rpcpass'] = input("RPC Password: ")
print("\n\tLocal Bitcoin Core Node connection.\n")
path['bitcoincli']= input("Insert the Path to Bitcoin-Cli: ")
pickle.dump(path, open("config/bclock.conf", "wb"))
artist()
except:
print("\n")
sys.exit(101)

View file

@ -0,0 +1,89 @@
import base64, codecs, json, requests
import pickle
import os
import sys
import simplejson as json
from cfonts import render, say
ndconnectload = {"ip_port":"", "tls":"", "macaroon":"", "ln":""}
settingsClock = {"gradient":"", "design":"", "colorA":"", "colorB":""}
def blogo():
if os.path.isfile('pyblocksettings.conf') or os.path.isfile('pyblocksettings.conf'): # Check if the file 'bclock.conf' is in the same folder
settingsv = pickle.load(open("pyblocksettings.conf", "rb")) # Load the file 'bclock.conf'
settings = settingsv # Copy the variable pathv to 'path'
else:
settings = {"gradient":"", "design":"block", "colorA":"green", "colorB":"yellow"}
pickle.dump(settings, open("pyblocksettings.conf", "wb"))
if settings["gradient"] == "grd":
output = render('PyBLOCK', gradient=[settings['colorA'], settings['colorB']], align='center', font=settings['design'])
else:
output = render('PyBLOCK', colors=[settings['colorA'], settings['colorB']], align='center', font=settings['design'])
print(output)
def clear(): # clear the screen
os.system('cls' if os.name=='nt' else 'clear')
if os.path.isfile('blndconnect.conf'): # Check if the file 'bclock.conf' is in the same folder
lndconnectData= pickle.load(open("blndconnect.conf", "rb")) # Load the file 'bclock.conf'
lndconnectload = lndconnectData # Copy the variable pathv to 'path'
else:
clear()
blogo()
print("\n\tIf you are going to use your local node leave IP:PORT/CERT/MACAROONS in blank.\n")
lndconnectload["ip_port"] = input("Insert IP:PORT to your node: ") # path to the bitcoin-cli
lndconnectload["tls"] = input("Insert the path to tls.cert file: ")
lndconnectload["macaroon"] = input("Insert the path to admin.macaroon: ")
print("\n\tLocal Lightning Node connection.\n")
lndconnectload["ln"] = input("Insert the path to lncli: ")
pickle.dump(lndconnectload, open("blndconnect.conf", "wb")) # Save the file 'bclock.conf'
def rpc(method, params=[]):
payload = json.dumps({
"jsonrpc": "2.0",
"id": "minebet",
"method": method,
"params": params
})
path = {"ip_port":"", "rpcuser":"", "rpcpass":"", "bitcoincli":""}
if os.path.isfile('bclock.conf'): # Check if the file 'bclock.conf' is in the same folder
pathv = pickle.load(open("bclock.conf", "rb")) # Load the file 'bclock.conf'
path = pathv # Copy the variable pathv to 'path'
return requests.post(path['ip_port'], auth=(path['rpcuser'], path['rpcpass']), data=payload).json()['result']
def remotegetblock():
if os.path.isfile('pyblocksettingsClock.conf') or os.path.isfile('pyblocksettingsClock.conf'): # Check if the file 'bclock.conf' is in the same folder
settingsv = pickle.load(open("pyblocksettingsClock.conf", "rb")) # Load the file 'bclock.conf'
settingsClock = settingsv # Copy the variable pathv to 'path'
else:
settingsClock = {"gradient":"", "design":"block", "colorA":"green", "colorB":"yellow"}
pickle.dump(settingsClock, open("pyblocksettingsClock.conf", "wb"))
b = rpc('getblockcount')
c = str(b)
a = c
output = render(str(c), colors=[settingsClock['colorA'], settingsClock['colorB']], align='center')
print("\x1b[?25l" + output)
while True:
x = a
b = rpc('getblockcount')
c = str(b)
if c > a:
clear()
blogo()
output = render(str(c), colors=[settingsClock['colorA'], settingsClock['colorB']], align='center')
print("\a\x1b[?25l" + output)
a = c
while True:
try:
clear()
blogo()
remotegetblock()
tmp()
except:
print("\n")
sys.exit(101)

30
pybitblock/SPV/clone.py Normal file
View file

@ -0,0 +1,30 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
import os
import os.path
import time as t
def gitclone():
url = "https://github.com/curly60e/satellite"
os.system("git clone " + url)
os.system("mkdir satellite/api/examples/.gnupg")
os.system("gpg --full-generate-key --homedir satellite/api/examples/.gnupg")
def satnode():
try:
os.system("python3 satellite/api/examples/demo-rx.py &")
t.sleep(5)
os.system("python3 satellite/api/examples/api_data_reader.py --demo --plaintext ")
except:
os.system("ps -ef | grep api_data_reader.py | grep -v grep | awk '{print $2}' | xargs kill -9")
os.system("ps -ef | grep demo-rx.py | grep -v grep | awk '{print $2}' | xargs kill -9")
def matrixsc():
if os.path.isdir('$HOME/pyblock/terminal_matrix'):
print("OK Pass")
else:
url = "https://github.com/curly60e/terminal_matrix.git"
os.system("git clone " + url)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

11
pybitblock/SPV/console.py Normal file
View file

@ -0,0 +1,11 @@
import os
import typer
def main():
scriptpath = os.path.join(os.path.dirname(__file__), 'PyBlock.py')
os.system(f"python3 {scriptpath}")
if __name__ == "__main__":
typer.run(main)

149
pybitblock/SPV/donation.py Normal file
View file

@ -0,0 +1,149 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
import requests
import qrcode
import pickle
from nodeconnection import *
def donationAddr():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
url = 'bc1qjzaz34nv2ev55vfdu9m5qh0zq0fwcn6c7pkcrv'
print("\033[1;30;47m")
qr.add_data(url)
qr.print_ascii()
print("\033[0;37;40m")
qr.clear()
print("Bitcoin Address Bech32: " + url)
def donationPayNym():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
url = 'PM8TJhNTTq3YVocXuPtLjKx7pKkdUxqwTerWJ2j2a7dNitgyMmBPN6gK61yE17N2vgvQvKYokXktt6D6GZFTmocvDJhaUJfHt7ehEMmthjsT3NQHseFM'
print("\033[1;30;47m")
qr.add_data(url)
qr.print_ascii()
print("\033[0;37;40m")
qr.clear()
print("PayNym: " + url)
#Dev LN
def donationLN():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
amt = input("Amount: ")
curl = 'curl -X POST https://lnbits.com/api/v1/payments -d ' + "'{" + """"out": false, "amount": {}, "memo": "Donation" """.format(amt) + "}'" + """ -H "X-Api-Key: 1d646820055e4e2da218e801eaacfc94 " -H "Content-type: application/json" """
sh = os.popen(curl).read()
clear()
blogo()
n = str(sh)
d = json.loads(n)
q = d['payment_request']
c = q.lower()
while True:
print("\033[1;30;47m")
qr.add_data(c)
qr.print_ascii()
print("\033[0;37;40m")
qr.clear()
print("Lightning Invoice: " + c)
dn = str(d['checking_id'])
t.sleep(10)
checkcurl = 'curl -X GET https://lnbits.com/api/v1/payments/' + dn + """ -H "X-Api-Key: 1d646820055e4e2da218e801eaacfc94" -H "Content-type: application/json" """
rsh = os.popen(checkcurl).read()
clear()
blogo()
nn = str(rsh)
dd = json.loads(nn)
db = dd['paid']
if db is not True:
continue
clear()
blogo()
tick()
bitLN['pd'] = "PAID"
#Tester Address
def donationAddrTst():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
url = 'bc1qwtzwu2evtchkvnf3ey6520yprsyv7vrjvhula5'
print("\033[1;30;47m")
qr.add_data(url)
qr.print_ascii()
print("\033[0;37;40m")
qr.clear()
print("Bitcoin Address Bech32: " + url)
#Tester LN
def donationLNTst():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
url = 'https://api.tippin.me/v1/public/addinvoice/__B__T__C__'
response = requests.get(url)
responseB = str(response.text)
responseC = responseB
lnreq = responseC.split(',')
lnbc1 = lnreq[1]
lnbc1S = str(lnbc1)
lnbc1R = lnbc1S.split(':')
lnbc1W = lnbc1R[1]
ln = str(lnbc1W)
ln1 = ln.strip('"')
node_not = input("Do you want to pay this tip with your node? Y/n: ")
if node_not in ["Y", "y"]:
lndconnectload = {"ip_port":"", "tls":"", "macaroon":"", "ln":""}
lndconnectData = pickle.load(open("blndconnect.conf", "rb")) # Load the file 'bclock.conf'
lndconnectload = lndconnectData # Copy the variable pathv to 'path'
if lndconnectload['ip_port']:
print("\nInvoice: " + ln1 + "\n")
payinvoice()
elif lndconnectload['ln']:
print("\nInvoice: " + ln1 + "\n")
localpayinvoice()
elif node_not in ["N", "n"]:
print("\033[1;30;47m")
qr.add_data(ln1)
qr.print_ascii()
print("\033[0;37;40m")
print("LND Invoice: " + ln1)
qr.clear()
response.close()
def decodeQR():
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
url = input("Insert your Bitcoin Address to show the QRCode: ")
print("\033[1;30;47m")
qr.add_data(url)
qr.print_ascii()
print("\033[0;37;40m")
qr.clear()
print("Bitcoin Address: " + url)

24
pybitblock/SPV/feed.py Normal file
View file

@ -0,0 +1,24 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
import os
import os.path
import time as t
def readFile():
try:
print ("\n\033[1;34;40mWaiting for new data...\n")
downloadsFolder = 'downloads/'
while True:
if not os.listdir(downloadsFolder):
continue
else:
print("\t\t\n\033[1;33;40mNew message from Space just arrived...\033[0;37;40m\n")
os.system("cat downloads/*")
os.system("rm downloads/*")
except:
os.system("ps -ef | grep api_data_reader.py | grep -v grep | awk '{print $2}' | xargs kill -9")
os.system("ps -ef | grep demo-rx.py | grep -v grep | awk '{print $2}' | xargs kill -9")

108
pybitblock/SPV/lnd.py Normal file
View file

@ -0,0 +1,108 @@
import base64
import os
from os.path import expanduser
import codecs
import grpc
import sys
from grpc_generated import router_pb2_grpc as lnrouterrpc, router_pb2 as lnrouter, rpc_pb2_grpc as lnrpc, rpc_pb2 as ln
MESSAGE_SIZE_MB = 50 * 1024 * 1024
def debug(message):
sys.stderr.write(message + "\n")
class Lnd:
def __init__(self, lnd_dir, server):
os.environ['GRPC_SSL_CIPHER_SUITES'] = 'HIGH+ECDSA'
lnd_dir = expanduser(lnd_dir)
combined_credentials = self.get_credentials(lnd_dir)
channel_options = [
('grpc.max_message_length', MESSAGE_SIZE_MB),
('grpc.max_receive_message_length', MESSAGE_SIZE_MB)
]
grpc_channel = grpc.secure_channel(server, combined_credentials, channel_options)
self.stub = lnrpc.LightningStub(grpc_channel)
self.router_stub = lnrouterrpc.RouterStub(grpc_channel)
self.graph = None
self.info = None
self.channels = None
@staticmethod
def get_credentials(lnd_dir):
tls_certificate = open(lnd_dir + '/tls.cert', 'rb').read()
ssl_credentials = grpc.ssl_channel_credentials(tls_certificate)
macaroon = codecs.encode(open(lnd_dir + '/data/chain/bitcoin/mainnet/admin.macaroon', 'rb').read(), 'hex')
auth_credentials = grpc.metadata_call_credentials(lambda _, callback: callback([('macaroon', macaroon)], None))
combined_credentials = grpc.composite_channel_credentials(ssl_credentials, auth_credentials)
return combined_credentials
def get_info(self):
if self.info is None:
self.info = self.stub.GetInfo(ln.GetInfoRequest())
return self.info
def get_graph(self):
if self.graph is None:
self.graph = self.stub.DescribeGraph(ln.ChannelGraphRequest(include_unannounced=True))
return self.graph
def get_own_pubkey(self):
return self.get_info().identity_pubkey
def get_edges(self):
return self.get_graph().edges
def generate_invoice(self, memo, amount):
invoice_request = ln.Invoice(
memo=memo,
value=amount,
)
add_invoice_response = self.stub.AddInvoice(invoice_request)
return self.decode_payment_request(add_invoice_response.payment_request)
def decode_payment_request(self, payment_request):
request = ln.PayReqString(
pay_req=payment_request,
)
return self.stub.DecodePayReq(request)
def get_channels(self):
if self.channels is None:
request = ln.ListChannelsRequest(
active_only=True,
)
self.channels = self.stub.ListChannels(request).channels
return self.channels
def get_route(self, pub_key, amount, ignored_edges, ignored_nodes, first_hop_channel_id):
if pub_key:
last_hop_pubkey = base64.b16decode(pub_key, True)
else:
last_hop_pubkey = None
request = ln.QueryRoutesRequest(
pub_key=self.get_own_pubkey(),
last_hop_pubkey=last_hop_pubkey,
amt=amount,
ignored_edges=ignored_edges,
ignored_nodes=ignored_nodes,
use_mission_control=True,
outgoing_chan_id=first_hop_channel_id,
)
try:
response = self.stub.QueryRoutes(request)
return response.routes
except:
return None
def send_payment(self, payment_request, route):
request = lnrouter.SendToRouteRequest(route=route)
request.payment_hash = self.hex_string_to_bytes(payment_request.payment_hash)
return self.router_stub.SendToRoute(request)
@staticmethod
def hex_string_to_bytes(hex_string):
decode_hex = codecs.getdecoder("hex_codec")
return decode_hex(hex_string)[0]

153
pybitblock/SPV/logic.py Normal file
View file

@ -0,0 +1,153 @@
import sys
from routes import Routes
DEFAULT_BASE_FEE_SAT_MSAT = 1000
DEFAULT_FEE_RATE_MSAT = 0.001
def debug(message):
sys.stderr.write(message + "\n")
def debugnobreak(message):
sys.stderr.write(message)
class Logic:
def __init__(self, lnd, first_hop_channel, last_hop_channel, amount, channel_ratio, excluded, max_fee_factor):
self.lnd = lnd
self.first_hop_channel = first_hop_channel
self.last_hop_channel = last_hop_channel
self.amount = amount
self.channel_ratio = channel_ratio
self.excluded = []
if excluded:
self.excluded = excluded
self.max_fee_factor = max_fee_factor
def rebalance(self):
if self.last_hop_channel:
debug(("Sending {:,} satoshis to rebalance to channel with ID %d"
% self.last_hop_channel.chan_id).format(self.amount))
else:
debug("Sending {:,} satoshis.".format(self.amount))
if self.channel_ratio != 0.5:
debug("Channel ratio used is %d%%" % int(self.channel_ratio * 100))
if self.first_hop_channel:
debug("Forced first channel has ID %d" % self.first_hop_channel.chan_id)
payment_request = self.generate_invoice()
routes = Routes(self.lnd, payment_request, self.first_hop_channel, self.last_hop_channel)
self.initialize_ignored_channels(routes)
tried_routes = []
while routes.has_next():
route = routes.get_next()
success = self.try_route(payment_request, route, routes, tried_routes)
if success:
return True
debug("Could not find any suitable route")
return False
def try_route(self, payment_request, route, routes, tried_routes):
if self.route_is_invalid(route, routes):
return False
tried_routes.append(route)
debug("")
debug("Trying route #%d" % len(tried_routes))
debug(Routes.print_route(route))
response = self.lnd.send_payment(payment_request, route)
is_successful = response.failure.code == 0
if is_successful:
debug("")
debug("")
debug("")
debug("Success! Paid fees: %s sat (%s msat)" % (route.total_fees, route.total_fees_msat))
debug("Successful route:")
debug(Routes.print_route(route))
debug("")
debug("")
debug("")
return True
else:
self.handle_error(response, route, routes)
return False
@staticmethod
def handle_error(response, route, routes):
code = response.failure.code
failure_source_pubkey = Logic.get_failure_source_pubkey(response, route)
if code == 15:
debugnobreak("Temporary channel failure, ")
routes.ignore_edge_on_route(failure_source_pubkey, route)
elif code == 18:
debugnobreak("Unknown next peer, ")
routes.ignore_edge_on_route(failure_source_pubkey, route)
elif code == 12:
debugnobreak("Fee insufficient, ")
routes.ignore_edge_on_route(failure_source_pubkey, route)
else:
debug(repr(response))
debug("Unknown error code %s" % repr(code))
@staticmethod
def get_failure_source_pubkey(response, route):
if response.failure.failure_source_index == 0:
failure_source_pubkey = route.hops[-1].pub_key
else:
failure_source_pubkey = route.hops[response.failure.failure_source_index - 1].pub_key
return failure_source_pubkey
def route_is_invalid(self, route, routes):
first_hop = route.hops[0]
if self.low_local_ratio_after_sending(first_hop, route.total_amt):
debugnobreak("Low local ratio after sending, ")
routes.ignore_first_hop(self.get_channel_for_channel_id(first_hop.chan_id))
return True
if self.fees_too_high(route):
routes.ignore_node_with_highest_fee(route)
return True
return False
def low_local_ratio_after_sending(self, first_hop, total_amount):
if self.first_hop_channel:
# Just use the computed/specified amount to drain the first hop, ignoring fees
return False
channel_id = first_hop.chan_id
channel = self.get_channel_for_channel_id(channel_id)
remote = channel.remote_balance + total_amount
local = channel.local_balance - total_amount
ratio = float(local) / (remote + local)
return ratio < self.channel_ratio
def fees_too_high(self, route):
hops_with_fees = len(route.hops) - 1
lnd_fees = hops_with_fees * (DEFAULT_BASE_FEE_SAT_MSAT + (self.amount * DEFAULT_FEE_RATE_MSAT))
limit = self.max_fee_factor * lnd_fees
return route.total_fees_msat > limit
def generate_invoice(self):
if self.last_hop_channel:
memo = "Rebalance of channel with ID %d" % self.last_hop_channel.chan_id
else:
memo = "Rebalance of channel with ID %d" % self.first_hop_channel.chan_id
return self.lnd.generate_invoice(memo, self.amount)
def get_channel_for_channel_id(self, channel_id):
for channel in self.lnd.get_channels():
if channel.chan_id == channel_id:
return channel
def initialize_ignored_channels(self, routes):
for channel in self.lnd.get_channels():
if self.low_local_ratio_after_sending(channel, self.amount):
routes.ignore_first_hop(channel, show_message=False)
if channel.chan_id in self.excluded:
debugnobreak("Channel is excluded, ")
routes.ignore_first_hop(channel)

112
pybitblock/SPV/logos.py Normal file
View file

@ -0,0 +1,112 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
def logoA():
print("""\n\n\033[1;33;40m
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*****@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@****************************#@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@***************************************@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@***********************************************@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@*****************************************************@@@@@@@@@@@@@
@@@@@@@@@@@***********************************************************@@@@@@@@@@
@@@@@@@@@****************************** *****************************@@@@@@@@
@@@@@@@******************************* *** ***********************@@@@@@
@@@@@@********************** .**** **** *************************@@@@@
@@@@*********************** ,* **************************@@@@
@@@**************************** ***************************@@
@@****************************** *. **********************#@
@@***************************** ******** *********************@
@****************************** *********** **********************
@***************************** *********** **********************
@***************************** ***********************
***************************** **************************
@*************************** ******** *************************
@*************************** ***********. ***********************
@********************* *** ************* ***********************
@@******************* ************ **********************@
@@******************** **********************@@
@@@************************** ,***********************@@
@@@@#*********************** *** *. **************************@@@@
@@@@@@********************* **** ***********************************@@@@@
@@@@@@@**************************** **********************************@@@@@@
@@@@@@@@@***************************************************************@@@@@@@@
@@@@@@@@@@@**********************************************************,@@@@@@@@@@
@@@@@@@@@@@@@@*****************************************************@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@***********************************************@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@***************************************@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@#***************************@@@@@@@@@@@@@@@@@@@@@@@@@@\033[0;37;40m
""")
def logoB():
print("""\n\n\033[1;33;40m
/////
////////////////////////////%
///////////////////////////////////////
///////////////////////////////////////////////
/////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
////////////////////////////// /////////////////////////////
/////////////////////////////// /// ///////////////////////
////////////////////// .//// //// /////////////////////////
/////////////////////// */ //////////////////////////
//////////////////////////// *//////////////////////////
////////////////////////////// /. //////////////////////
///////////////////////////// //////// /////////////////////
////////////////////////////// //////////* //////////////////////
///////////////////////////// /////////// //////////////////////
///////////////////////////// ///////////////////////
///////////////////////////// */////////////////////////
/////////////////////////// //////// /////////////////////////
/////////////////////////// ///////////, ///////////////////////
///////////////////// /// ///////////// ///////////////////////
/////////////////// //////////// //////////////////////
//////////////////// //////////////////////
////////////////////////// *///////////////////////
%/////////////////////// /// /. //////////////////////////
///////////////////// //// ///////////////////////////////////
//////////////////////////// //////////////////////////////////
///////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////*
/////////////////////////////////////////////////////
///////////////////////////////////////////////
///////////////////////////////////////
%///////////////////////////
/////\033[0;37;40m
""")
def logoC():
print("""\n\n\033[1;33;40m
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@
@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@
@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@
@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&& &&&&&&&&&&&&&&&&&&&&&&&@@@@@@
@@@@@@&&&&&&&&&&&&&&&&&&&&&& *&&&& &&&& &&&&&&&&&&&&&&&&&&&&&&&&&@@@@@
@@@@&&&&&&&&&&&&&&&&&&&&&&& #& &&&&&&&&&&&&&&&&&&&&&&&&&&@@@@
@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&. %&&&&&&&&&&&&&&&&&&&&&&&&&&@@
@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &, &&&&&&&&&&&&&&&&&&&&&&@@
@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&. &&&&&&&& &&&&&&&&&&&&&&&&&&&&&@
@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&% &&&&&&&&&&&&&&&&&&&&&&
@&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&
@&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&& %&&&&&&&&&&&&&&&&&&&&&&&&&
@&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&
@&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&/ &&&&&&&&&&&&&&&&&&&&&&&
@&&&&&&&&&&&&&&&&&&&&& &&& &&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&
@@&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&@
@@&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&@@
@@@&&&&&&&&&&&&&&&&&&&&&&&&&& %&&&&&&&&&&&&&&&&&&&&&&&@@
@@@@@&&&&&&&&&&&&&&&&&&&&&&& &&& &, &&&&&&&&&&&&&&&&&&&&&&&&&&@@@@
@@@@@@&&&&&&&&&&&&&&&&&&&&& &&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@
@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@
@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@
@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@
@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@\033[0;37;40m
""")

File diff suppressed because it is too large Load diff

69
pybitblock/SPV/pblogo.py Normal file
View file

@ -0,0 +1,69 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
import os
import pickle
from cfonts import render, say
def blogo():
if os.path.isfile('config/pyblocksettinconfig/gs.conf') or os.path.isfile('config/pyblocksettings.conf'): # Check if the file 'bclock.conf' is in the same folder
settingsv = pickle.load(open("config/pyblocksettings.conf", "rb")) # Load the file 'bclock.conf'
settings = settingsv # Copy the variable pathv to 'path'
else:
settings = {"gradient":"", "design":"block", "colorA":"green", "colorB":"yellow"}
pickle.dump(settings, open("config/pyblocksettings.conf", "wb"))
if settings["gradient"] == "grd":
output = render('PyBLOCK', gradient=[settings['colorA'], settings['colorB']], align='left', font=settings['design'])
else:
output = render('PyBLOCK', colors=[settings['colorA'], settings['colorB']], align='left', font=settings['design'])
print(output)
def tick():
print("""\033[1;32;40m
@
@
@
@@
@@
@@@
@@@ @@.
@@@@@@@
@@@@@@@@
@@@@
@@@@
@ @@@@
@@@@@@@@
@@@@@@@@
@@@
@@@
@@
@@
@
@
\033[0;37;40m""")
def canceled():
print("""
) ( (
( ( ( /( ( )\ ) )\ )
)\ )\ )\()) )\ ( (()/( ( (()/(
(((_)((((_)( ((_)\ (((_) )\ /(_)) )\ /(_))
)\___ )\ _ )\ _((_) )\___ ((_) (_)) ((_)(_))_
((/ __|(_)_\(_)| \| |((/ __|| __|| | | __|| \
| (__ / _ \ | .` | | (__ | _| | |__ | _| | |) |
\___|/_/ \_\ |_|\_| \___||___||____||___||___/
""")

2180
pybitblock/SPV/ppi.py Normal file

File diff suppressed because it is too large Load diff

256
pybitblock/SPV/rebalance.py Normal file
View file

@ -0,0 +1,256 @@
#!/usr/bin/env python
import argparse
import math
import os
import platform
import sys
from lnd import Lnd
from logic import Logic
MAX_CHANNEL_CAPACITY = 16777215
MAX_SATOSHIS_PER_TRANSACTION = 4294967
def main():
argument_parser = get_argument_parser()
arguments = argument_parser.parse_args()
lnd = Lnd(arguments.lnddir, arguments.grpc)
first_hop_channel_id = vars(arguments)['from']
to_channel = arguments.to
if arguments.ratio < 1 or arguments.ratio > 50:
print("--ratio must be between 1 and 50")
sys.exit(1)
channel_ratio = float(arguments.ratio) / 100
if arguments.incoming is not None and not arguments.list_candidates:
print("--outgoing and --incoming only work in conjunction with --list-candidates")
sys.exit(1)
if arguments.list_candidates:
incoming = arguments.incoming is None or arguments.incoming
if incoming:
list_incoming_candidates(lnd, channel_ratio)
else:
list_outgoing_candidates(lnd, channel_ratio)
sys.exit(0)
if to_channel is None and first_hop_channel_id is None:
argument_parser.print_help()
sys.exit(1)
percentage = arguments.percentage
if percentage:
if percentage < 1 or percentage > 100:
print("--percentage must be between 1 and 100")
argument_parser.print_help()
sys.exit(1)
# the 'to' argument might be an index, or a channel ID
if to_channel and to_channel < 10000:
# here we are in the "channel index" case
index = int(to_channel) - 1
candidates = get_incoming_rebalance_candidates(lnd, channel_ratio)
candidate = candidates[index]
last_hop_channel = candidate
else:
# else the channel argument should be the channel ID
last_hop_channel = get_channel_for_channel_id(lnd, to_channel)
first_hop_channel = get_channel_for_channel_id(lnd, first_hop_channel_id)
amount = get_amount(arguments, first_hop_channel, last_hop_channel)
if amount == 0:
print("Amount is 0, nothing to do")
sys.exit(0)
max_fee_factor = arguments.max_fee_factor
excluded = arguments.exclude
return Logic(lnd, first_hop_channel, last_hop_channel, amount, channel_ratio, excluded,
max_fee_factor).rebalance()
def get_amount(arguments, first_hop_channel, last_hop_channel):
if last_hop_channel:
amount = get_rebalance_amount(last_hop_channel)
else:
amount = get_rebalance_amount(first_hop_channel)
if arguments.percentage:
amount = int(round(amount * arguments.percentage / 100))
if last_hop_channel and first_hop_channel:
rebalance_amount_from_channel = get_rebalance_amount(first_hop_channel)
amount = min(amount, rebalance_amount_from_channel)
if arguments.amount:
amount = min(amount, int(arguments.amount))
amount = min(amount, MAX_SATOSHIS_PER_TRANSACTION)
return amount
def get_channel_for_channel_id(lnd, channel_id):
for channel in lnd.get_channels():
if channel.chan_id == channel_id:
return channel
return None
def get_argument_parser():
parser = argparse.ArgumentParser()
parser.add_argument("--lnddir",
default="~/.lnd",
dest="lnddir",
help="(default ~/.lnd) lnd directory")
parser.add_argument("--grpc",
default="localhost:10009",
dest="grpc",
help="(default localhost:10009) lnd gRPC endpoint")
parser.add_argument("-r", "--ratio",
type=int,
default=50,
help="(default: 50) ratio for channel imbalance between 1 and 50, "
"eg. 45 to only show channels (-l) with less than 45%% of the "
"funds on the local (-i) or remote (-o) side")
list_group = parser.add_argument_group("list candidates", "Show the unbalanced channels.")
list_group.add_argument("-l", "--list-candidates", action="store_true",
help="list candidate channels for rebalance")
direction_group = list_group.add_mutually_exclusive_group()
direction_group.add_argument("-o", "--outgoing",
action="store_const",
const=False,
dest="incoming",
help="lists channels with less than x%% of the funds on the remote side (see --ratio)")
direction_group.add_argument("-i", "--incoming",
action="store_const",
const=True,
dest="incoming",
help="(default) lists channels with less than x%% of the funds on the local side "
"(see --ratio)")
rebalance_group = parser.add_argument_group("rebalance",
"Rebalance a channel. You need to specify at least"
" the 'from' channel (-f) or the 'to' channel (-t).")
rebalance_group.add_argument("-f", "--from",
metavar="CHANNEL",
type=int,
help="channel ID of the outgoing channel "
"(funds will be taken from this channel)")
rebalance_group.add_argument("-t", "--to",
metavar="CHANNEL",
type=int,
help="channel ID of the incoming channel "
"(funds will be sent to this channel). "
"You may also use the index as shown in the incoming candidate list (-l -i).")
amount_group = rebalance_group.add_mutually_exclusive_group()
amount_group.add_argument("-a", "--amount",
type=int,
help="Amount of the rebalance, in satoshis. If not specified, "
"the amount computed for a perfect rebalance will be used"
" (up to the maximum of 4,294,967 satoshis)")
amount_group.add_argument("-p", "--percentage",
type=int,
help="Set the amount to send to a percentage of the amount required to rebalance. "
"As an example, if this is set to 50, the amount will half of the default. "
"See --amount.")
rebalance_group.add_argument("-e", "--exclude",
type=int,
action="append",
help="Exclude the given channel ID as the outgoing channel (no funds will be taken "
"out of excluded channels)")
rebalance_group.add_argument("--max-fee-factor",
type=float,
default=10,
help="(default: 10) Reject routes that cost more than x times the lnd default "
"(base: 1 sat, rate: 1 millionth sat) per hop on average")
return parser
def list_incoming_candidates(lnd, channel_ratio):
candidates = get_incoming_rebalance_candidates(lnd, channel_ratio)
list_candidates(candidates)
def list_outgoing_candidates(lnd, channel_ratio):
candidates = get_outgoing_rebalance_candidates(lnd, channel_ratio)
list_candidates(candidates)
def list_candidates(candidates):
index = 0
for candidate in candidates:
index += 1
rebalance_amount_int = get_rebalance_amount(candidate)
rebalance_amount = "{:,}".format(rebalance_amount_int)
if rebalance_amount_int > MAX_SATOSHIS_PER_TRANSACTION:
rebalance_amount += " (max per transaction: {:,})".format(MAX_SATOSHIS_PER_TRANSACTION)
print("(%2d) Channel ID: " % index + str(candidate.chan_id))
print("Pubkey: " + candidate.remote_pubkey)
print("Local ratio: {:.3f}".format(get_local_ratio(candidate)))
print("Capacity: {:,}".format(candidate.capacity))
print("Remote balance: {:,}".format(candidate.remote_balance))
print("Local balance: {:,}".format(candidate.local_balance))
print("Amount for 50-50: " + rebalance_amount)
print(get_capacity_and_ratio_bar(candidate))
print("")
def get_rebalance_amount(channel):
return abs(int(math.ceil(float(get_remote_surplus(channel)) / 2)))
def get_incoming_rebalance_candidates(lnd, channel_ratio):
low_local = list(filter(lambda c: get_local_ratio(c) < channel_ratio, lnd.get_channels()))
low_local = list(filter(lambda c: get_rebalance_amount(c) > 0, low_local))
return sorted(low_local, key=get_remote_surplus, reverse=False)
def get_outgoing_rebalance_candidates(lnd, channel_ratio):
high_local = list(filter(lambda c: get_local_ratio(c) > 1 - channel_ratio, lnd.get_channels()))
high_local = list(filter(lambda c: get_rebalance_amount(c) > 0, high_local))
return sorted(high_local, key=get_remote_surplus, reverse=True)
def get_local_ratio(channel):
remote = channel.remote_balance
local = channel.local_balance
return float(local) / (remote + local)
def get_remote_surplus(channel):
return channel.remote_balance - channel.local_balance
def get_capacity_and_ratio_bar(candidate):
columns = get_columns()
columns_scaled_to_capacity = int(round(columns * float(candidate.capacity) / MAX_CHANNEL_CAPACITY))
bar_width = columns_scaled_to_capacity - 2
result = "|"
ratio = get_local_ratio(candidate)
length = int(round(ratio * bar_width))
for x in range(0, length):
result += "="
for x in range(length, bar_width):
result += " "
return result + "|"
def get_columns():
if platform.system() == 'Linux' and sys.__stdin__.isatty():
return int(os.popen('stty size', 'r').read().split()[1])
else:
return 80
success = main()
if success:
sys.exit(0)
sys.exit(1)

115
pybitblock/SPV/routes.py Normal file
View file

@ -0,0 +1,115 @@
import base64
import sys
MAX_ROUTES_TO_REQUEST = 100
def debug(message):
sys.stderr.write(message + "\n")
def debugnobreak(message):
sys.stderr.write(message)
class Routes:
def __init__(self, lnd, payment_request, first_hop_channel, last_hop_channel):
self.lnd = lnd
self.payment_request = payment_request
self.first_hop_channel = first_hop_channel
self.last_hop_channel = last_hop_channel
self.all_routes = []
self.returned_routes = []
self.ignored_edges = []
self.ignored_nodes = []
self.num_requested_routes = 0
def has_next(self):
self.update_routes()
return self.returned_routes < self.all_routes
def get_next(self):
self.update_routes()
for route in self.all_routes:
if route not in self.returned_routes:
self.returned_routes.append(route)
return route
return None
def update_routes(self):
while True:
if self.returned_routes < self.all_routes:
return
if self.num_requested_routes >= MAX_ROUTES_TO_REQUEST:
return
self.request_route()
def request_route(self):
amount = self.get_amount()
if self.last_hop_channel:
last_hop_pubkey = self.last_hop_channel.remote_pubkey
else:
last_hop_pubkey = None
if self.first_hop_channel:
first_hop_channel_id = self.first_hop_channel.chan_id
else:
first_hop_channel_id = None
routes = self.lnd.get_route(last_hop_pubkey, amount, self.ignored_edges,
self.ignored_nodes, first_hop_channel_id)
if routes is None:
self.num_requested_routes = MAX_ROUTES_TO_REQUEST
else:
self.num_requested_routes += 1
for route in routes:
self.add_route(route)
def add_route(self, route):
if route is None:
return
if route not in self.all_routes:
self.all_routes.append(route)
@staticmethod
def print_route(route):
route_str = " -> ".join(str(h.chan_id) for h in route.hops)
return route_str
def get_amount(self):
return self.payment_request.num_satoshis
def ignore_first_hop(self, channel, show_message=True):
own_key = self.lnd.get_own_pubkey()
other_key = channel.remote_pubkey
self.ignore_edge_from_to(channel.chan_id, own_key, other_key, show_message)
def ignore_edge_on_route(self, failure_source_pubkey, route):
ignore_next = False
for hop in route.hops:
if ignore_next:
self.ignore_edge_from_to(hop.chan_id, failure_source_pubkey, hop.pub_key)
return
if hop.pub_key == failure_source_pubkey:
ignore_next = True
def ignore_node_with_highest_fee(self, route):
max_fee_msat = 0
max_fee_hop = None
for hop in route.hops:
if hop.fee_msat > max_fee_msat:
max_fee_msat = hop.fee_msat
max_fee_hop = hop
pub_key = max_fee_hop.pub_key
debugnobreak("High fees (%s msat), " % max_fee_msat)
self.ignore_node(pub_key)
def ignore_edge_from_to(self, chan_id, from_pubkey, to_pubkey, show_message=True):
if show_message:
debug("ignoring channel %s (from %s to %s)" % (chan_id, from_pubkey, to_pubkey))
direction_reverse = from_pubkey > to_pubkey
edge = {"channel_id": chan_id, "direction_reverse": direction_reverse}
self.ignored_edges.append(edge)
def ignore_node(self, pub_key):
debug("ignoring node %s" % pub_key)
self.ignored_nodes.append(base64.b16decode(pub_key, True))

27
pybitblock/SPV/sysinf.py Normal file
View file

@ -0,0 +1,27 @@
#Developer: Curly60e
#PyBLOCK its a clock of the Bitcoin blockchain.
import os
import psutil
import time as t
from pblogo import *
def clear(): # clear the screen
os.system('cls' if os.name=='nt' else 'clear')
def sysinfoDetail(): #Cpu and memory usage
# gives a single float value
while True:
try:
clear()
blogo()
print(" \033[0;37;40m----------------------------")
print(" \033[3;33;40mCPU Usage: \033[1;32;40m" + str(psutil.cpu_percent()) + "\033[0;37;40m%")
print(" \033[3;33;40mMemory Usage: \033[1;32;40m" "{}\033[0;37;40m%".format(int(psutil.virtual_memory().percent)))
print(" \033[3;33;40mMemory Available: \033[1;32;40m" "{} \033[0;37;40mMB".format(int(psutil.virtual_memory().available / 1024 / 1024)))
print(" \033[3;33;40mDisk Usage: \033[1;32;40m" "{}%\033[0;37;40m%".format(psutil.disk_usage('/').percent))
print(" \033[0;37;40m----------------------------")
t.sleep(1)
except:
break