mirror of
https://github.com/cryptoadvance/specter-desktop.git
synced 2026-08-13 12:33:29 +02:00
autodetect json-rpc including cookies
This commit is contained in:
parent
56cc976bbd
commit
43d165df54
3 changed files with 148 additions and 102 deletions
123
rpc.py
123
rpc.py
|
|
@ -1,9 +1,132 @@
|
|||
import requests, json, os
|
||||
import os, sys, errno
|
||||
|
||||
# TODO: redefine __dir__ and help
|
||||
|
||||
RPC_PORTS = { "test": 18332, "regtest": 18443, "main": 8332, 'signet': 38332 }
|
||||
|
||||
def get_default_datadir():
|
||||
datadir = None
|
||||
if sys.platform == 'darwin':
|
||||
datadir = os.path.join(os.environ['HOME'], "Library/Application Support/Bitcoin/")
|
||||
elif sys.platform == 'win32':
|
||||
datadir = os.path.join(os.environ['HOME'], "Bitcoin")
|
||||
else:
|
||||
datadir = os.path.join(os.environ['HOME'], ".bitcoin")
|
||||
return datadir
|
||||
|
||||
def get_rpcconfig():
|
||||
path = get_default_datadir()
|
||||
config = {
|
||||
"bitcoin.conf": {},
|
||||
"cookies": [],
|
||||
}
|
||||
if not os.path.isdir(path): # we don't know where to search for files
|
||||
return config
|
||||
# load content from bitcoin.conf
|
||||
bitcoin_conf_file = os.path.join(path, "bitcoin.conf")
|
||||
if os.path.exists(bitcoin_conf_file):
|
||||
try:
|
||||
with open(bitcoin_conf_file, 'r') as f:
|
||||
for line in f.readlines():
|
||||
line = line.split("#")[0]
|
||||
if '=' not in line:
|
||||
continue
|
||||
k, v = line.split('=', 1)
|
||||
config["bitcoin.conf"][k.strip()] = v.strip()
|
||||
except:
|
||||
print("Can't open %s file" % bitcoin_conf_file)
|
||||
folders = {
|
||||
"main": "",
|
||||
"test": "testnet3",
|
||||
"regtest": "regtest",
|
||||
"signet": "signet",
|
||||
}
|
||||
for chain in folders:
|
||||
fname = os.path.join(path, folders[chain], ".cookie")
|
||||
if os.path.exists(fname):
|
||||
try:
|
||||
with open(fname, 'r') as f:
|
||||
content = f.read()
|
||||
user, passwd = content.split(":")
|
||||
obj = {
|
||||
"user": user,
|
||||
"passwd": passwd,
|
||||
"port": RPC_PORTS[chain]
|
||||
}
|
||||
config["cookies"].append(obj)
|
||||
except:
|
||||
print("Can't open %s file" % fname)
|
||||
return config
|
||||
|
||||
def get_configs(config=None):
|
||||
if config is None:
|
||||
config = get_rpcconfig()
|
||||
confs = []
|
||||
default = {}
|
||||
if "rpcuser" in config["bitcoin.conf"]:
|
||||
default["user"] = config["bitcoin.conf"]["rpcuser"]
|
||||
if "rpcpassword" in config["bitcoin.conf"]:
|
||||
default["passwd"] = config["bitcoin.conf"]["rpcpassword"]
|
||||
if "rpchost" in config["bitcoin.conf"]:
|
||||
default["host"] = config["bitcoin.conf"]["rpchost"]
|
||||
if "rpcport" in config["bitcoin.conf"]:
|
||||
default["port"] = int(config["bitcoin.conf"]["rpcport"])
|
||||
if "user" in default and "passwd" in default:
|
||||
if "port" in default: # only one bitcoin-cli makes sense in this case
|
||||
confs.append(default)
|
||||
return confs
|
||||
else:
|
||||
for network in RPC_PORTS:
|
||||
o = {"port": RPC_PORTS[network]}
|
||||
o.update(default)
|
||||
confs.append(o)
|
||||
return confs
|
||||
# try cookies now
|
||||
for cookie in config["cookies"]:
|
||||
o = {}
|
||||
o.update(default)
|
||||
print(cookie)
|
||||
o.update(cookie)
|
||||
confs.append(o)
|
||||
return confs
|
||||
|
||||
def detect_cli(config=None):
|
||||
if config is None:
|
||||
config = get_rpcconfig()
|
||||
rpcconfs = get_configs(config)
|
||||
cli_arr = []
|
||||
for conf in rpcconfs:
|
||||
print(conf)
|
||||
cli_arr.append(BitcoinCLI(**conf))
|
||||
return cli_arr
|
||||
|
||||
def autodetect_cli(port=None):
|
||||
if port == "":
|
||||
port = None
|
||||
if port is not None:
|
||||
port = int(port)
|
||||
cli_arr = detect_cli()
|
||||
available_cli_arr = []
|
||||
if len(cli_arr) > 0:
|
||||
print("trying %d different configs" % len(cli_arr))
|
||||
for cli in cli_arr:
|
||||
if port is not None:
|
||||
if int(cli.port) != port:
|
||||
continue
|
||||
try:
|
||||
print(cli.getmininginfo())
|
||||
print("Yey! Bitcoin-cli found!")
|
||||
available_cli_arr.append(cli)
|
||||
except requests.exceptions.RequestException:
|
||||
print("can't connect")
|
||||
except Exception as e:
|
||||
print("fail...", e)
|
||||
else:
|
||||
print("Bitcoin-cli not found :(")
|
||||
print("Detected %d bitcoin daemons" % len(available_cli_arr))
|
||||
return available_cli_arr
|
||||
|
||||
class BitcoinCLI:
|
||||
def __init__(self, user, passwd, host="127.0.0.1", port=8332, protocol="http", path="", timeout=30, **kwargs):
|
||||
path = path.replace("//","/") # just in case
|
||||
|
|
|
|||
94
rpctest.py
94
rpctest.py
|
|
@ -2,100 +2,6 @@ import os, sys, errno
|
|||
from rpc import *
|
||||
import requests
|
||||
|
||||
def get_default_datadir():
|
||||
datadir = None
|
||||
if sys.platform == 'darwin':
|
||||
datadir = os.path.join(os.environ['HOME'], "Library/Application Support/Bitcoin/")
|
||||
elif sys.platform == 'win32':
|
||||
datadir = os.path.join(os.environ['HOME'], "Bitcoin")
|
||||
else:
|
||||
datadir = os.path.join(os.environ['HOME'], ".bitcoin")
|
||||
return datadir
|
||||
|
||||
def get_rpcconfig():
|
||||
path = get_default_datadir()
|
||||
config = {
|
||||
"bitcoin.conf": {},
|
||||
"cookies": [],
|
||||
}
|
||||
if not os.path.isdir(path): # we don't know where to search for files
|
||||
return config
|
||||
# load content from bitcoin.conf
|
||||
bitcoin_conf_file = os.path.join(path, "bitcoin.conf")
|
||||
if os.path.exists(bitcoin_conf_file):
|
||||
try:
|
||||
with open(bitcoin_conf_file, 'r') as f:
|
||||
for line in f.readlines():
|
||||
line = line.split("#")[0]
|
||||
if '=' not in line:
|
||||
continue
|
||||
k, v = line.split('=', 1)
|
||||
config["bitcoin.conf"][k.strip()] = v.strip()
|
||||
except:
|
||||
print("Can't open %s file" % bitcoin_conf_file)
|
||||
folders = {
|
||||
"main": "",
|
||||
"test": "testnet3",
|
||||
"regtest": "regtest",
|
||||
"signet": "signet",
|
||||
}
|
||||
for chain in folders:
|
||||
fname = os.path.join(path, folders[chain], ".cookie")
|
||||
if os.path.exists(fname):
|
||||
try:
|
||||
with open(fname, 'r') as f:
|
||||
content = f.read()
|
||||
user, passwd = content.split(":")
|
||||
obj = {
|
||||
"user": user,
|
||||
"passwd": passwd,
|
||||
"port": RPC_PORTS[chain]
|
||||
}
|
||||
config["cookies"].append(obj)
|
||||
except:
|
||||
print("Can't open %s file" % fname)
|
||||
return config
|
||||
|
||||
def get_configs(config):
|
||||
confs = []
|
||||
default = {}
|
||||
if "rpcuser" in config["bitcoin.conf"]:
|
||||
default["user"] = config["bitcoin.conf"]["rpcuser"]
|
||||
if "rpcpassword" in config["bitcoin.conf"]:
|
||||
default["passwd"] = config["bitcoin.conf"]["rpcpassword"]
|
||||
if "rpchost" in config["bitcoin.conf"]:
|
||||
default["host"] = config["bitcoin.conf"]["rpchost"]
|
||||
if "rpcport" in config["bitcoin.conf"]:
|
||||
default["port"] = int(config["bitcoin.conf"]["rpcport"])
|
||||
if "user" in default and "passwd" in default:
|
||||
if "port" in default: # only one bitcoin-cli makes sense in this case
|
||||
confs.append(default)
|
||||
return confs
|
||||
else:
|
||||
for network in RPC_PORTS:
|
||||
o = {"port": RPC_PORTS[network]}
|
||||
o.update(default)
|
||||
confs.append(o)
|
||||
return confs
|
||||
# try cookies now
|
||||
for cookie in config["cookies"]:
|
||||
o = {}
|
||||
o.update(default)
|
||||
print(cookie)
|
||||
o.update(cookie)
|
||||
confs.append(o)
|
||||
return confs
|
||||
|
||||
def detect_cli(config=None):
|
||||
if config is None:
|
||||
config = get_rpcconfig()
|
||||
rpcconfs = get_configs(config)
|
||||
cli_arr = []
|
||||
for conf in rpcconfs:
|
||||
print(conf)
|
||||
cli_arr.append(BitcoinCLI(**conf))
|
||||
return cli_arr
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli_arr = detect_cli()
|
||||
available_cli_arr = []
|
||||
|
|
|
|||
33
specter.py
33
specter.py
|
|
@ -1,4 +1,4 @@
|
|||
from rpc import BitcoinCLI, RPC_PORTS
|
||||
from rpc import BitcoinCLI, RPC_PORTS, autodetect_cli
|
||||
import os, json, copy
|
||||
from helpers import deep_update, load_jsons
|
||||
from collections import OrderedDict
|
||||
|
|
@ -59,6 +59,23 @@ def alias(name):
|
|||
name = name.replace(" ", "_")
|
||||
return "".join(x for x in name if x.isalnum() or x=="_").lower()
|
||||
|
||||
def get_cli(conf):
|
||||
if "user" not in conf or conf["user"]=="":
|
||||
conf["autodetect"] = True
|
||||
if conf["autodetect"]:
|
||||
if "port" in conf:
|
||||
cli_arr = autodetect_cli(port=conf["port"])
|
||||
else:
|
||||
cli_arr = autodetect_cli()
|
||||
if len(cli_arr) > 0:
|
||||
cli = cli_arr[0]
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
cli = BitcoinCLI(conf["user"], conf["password"],
|
||||
host=conf["host"], port=conf["port"], protocol=conf["protocol"])
|
||||
return cli
|
||||
|
||||
class Specter:
|
||||
def __init__(self, data_folder="./data", config={}):
|
||||
if data_folder.startswith("~"):
|
||||
|
|
@ -74,6 +91,7 @@ class Specter:
|
|||
# default config
|
||||
self.config = {
|
||||
"rpc": {
|
||||
"autodetect": True,
|
||||
"user": None,
|
||||
"password": None,
|
||||
"port": RPC_PORTS["main"],
|
||||
|
|
@ -107,12 +125,11 @@ class Specter:
|
|||
# init arguments
|
||||
deep_update(self.config, self.arg_config) # override loaded config
|
||||
|
||||
# check if we have user, password and can connect
|
||||
self._is_configured = bool(self.config["rpc"]["user"] and self.config["rpc"]["password"])
|
||||
self.cli = get_cli(self.config["rpc"])
|
||||
print(self.cli)
|
||||
self._is_configured = (self.cli is not None)
|
||||
self._is_running = False
|
||||
if self._is_configured:
|
||||
self.cli = BitcoinCLI(self.config["rpc"]["user"], self.config["rpc"]["password"],
|
||||
host=self.config["rpc"]["host"], port=self.config["rpc"]["port"], protocol=self.config["rpc"]["protocol"])
|
||||
try:
|
||||
self._info = self.cli.getmininginfo()
|
||||
self._is_running = True
|
||||
|
|
@ -140,12 +157,12 @@ class Specter:
|
|||
except Exception as e:
|
||||
print("can't load wallets...", e)
|
||||
|
||||
|
||||
def test_rpc(self, **kwargs):
|
||||
conf = copy.deepcopy(self.config["rpc"])
|
||||
conf.update(kwargs)
|
||||
cli = BitcoinCLI(conf["user"], conf["password"],
|
||||
host=conf["host"], port=conf["port"], protocol=conf["protocol"])
|
||||
cli = get_cli(conf)
|
||||
if cli is None:
|
||||
return {"out": "", "err": "autodetect failed", "code": -1}
|
||||
r = {}
|
||||
try:
|
||||
r["out"] = json.dumps(cli.getmininginfo(),indent=4)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue