electrum-personal-server

Maximally lightweight electrum server for a single user
git clone https://git.parazyd.org/electrum-personal-server
Log | Files | Refs | README

commit a1fe3f1b72007ab7cc6c360dc79d5137949e8ef1
parent 2d881814621c6e6ee7b9888eb68b2e87e1886a85
Author: chris-belcher <chris-belcher@users.noreply.github.com>
Date:   Mon, 26 Mar 2018 01:49:15 +0100

now searches for the .cookie file for rpc auth, user can also configure datadir in config file, default datadirs are untested

Diffstat:
MREADME.md | 6+++---
Mconfig.cfg_sample | 4++--
Mserver.py | 30+++++++++++++++++++++++++++---
Mtransactionmonitor.py | 2+-
4 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md @@ -46,9 +46,9 @@ of any binaries before running them, or compile from source. Download the latest release or clone the git repository. Enter the directory and rename the file `config.cfg_sample` to `config.cfg`, edit this file to -configure your bitcoin node json-rpc authentication details. Next add your -wallet master public keys or watch-only addresses to the `[master-public-keys]` -and `[watch-only-addresses]` sections. +configure everything about the server. Add your wallet master public keys or +watch-only addresses to the `[master-public-keys]` and `[watch-only-addresses]` +sections. Finally run `./server.py` on Linux or double-click `run-server.bat` on Windows. The first time the server is run it will import all configured addresses as diff --git a/config.cfg_sample b/config.cfg_sample @@ -22,8 +22,8 @@ [bitcoin-rpc] host = localhost port = 8332 -user = bitcoinrpc -password = password +#empty means look in the default location +datadir = # how often in seconds to poll for new transactions when electrum not connected poll_interval_listening = 30 diff --git a/server.py b/server.py @@ -3,7 +3,7 @@ #the electrum protocol uses hash(scriptpubkey) as a key for lookups # as an alternative to address or scriptpubkey -import socket, time, json, datetime, struct, binascii, ssl +import socket, time, json, datetime, struct, binascii, ssl, os.path, platform from configparser import ConfigParser, NoSectionError from jsonrpc import JsonRpc, JsonRpcError @@ -364,6 +364,27 @@ def import_addresses(rpc, addrs): et = time.time() debug("imported addresses in " + str(et - st) + " sec") +def obtain_rpc_username_password(datadir): + if len(datadir.strip()) == 0: + debug("no datadir configuration, checking in default location") + systemname = platform.system() + #paths from https://en.bitcoin.it/wiki/Data_directory + if systemname == "Linux": + datadir = os.path.expanduser("~/.bitcoin") + elif systemname == "Windows": + datadir = os.path.expandvars("%APPDATA%\Bitcoin") + elif systemname == "Darwin": #mac os + datadir = os.path.expanduser( + "~/Library/Application Support/Bitcoin/") + cookie_path = os.path.join(datadir, ".cookie") + if not os.path.exists(cookie_path): + log("Unable to find .cookie file, try setting `datadir` config") + return None, None + fd = open(cookie_path) + username, password = fd.read().strip().split(":") + fd.close() + return username, password + def main(): try: config = ConfigParser() @@ -372,10 +393,13 @@ def main(): except NoSectionError: log("Non-existant configuration file `config.cfg`") return + rpc_u, rpc_p = obtain_rpc_username_password(config.get( + "bitcoin-rpc", "datadir")) + if rpc_u == None: + return rpc = JsonRpc(host = config.get("bitcoin-rpc", "host"), port = int(config.get("bitcoin-rpc", "port")), - user = config.get("bitcoin-rpc", "user"), - password = config.get("bitcoin-rpc", "password")) + user = rpc_u, password = rpc_p) #TODO somewhere here loop until rpc works and fully sync'd, to allow # people to run this script without waiting for their node to fully diff --git a/transactionmonitor.py b/transactionmonitor.py @@ -119,9 +119,9 @@ class TransactionMonitor(object): s.debug("last_known_recent_txid = " + str(self.last_known_recent_txid)) et = time.time() + s.debug("address_history =\n" + pprint.pformat(address_history)) s.log("Found " + str(count) + " txes. History built in " + str(et - st) + "sec") - s.debug("address_history =\n" + pprint.pformat(address_history)) self.address_history = address_history self.unconfirmed_txes = unconfirmed_txes return True