From 65600d1da418d724ba37cb702f570f32ed56c4d1 Mon Sep 17 00:00:00 2001 From: Lawrence Deacon Date: Fri, 17 Sep 2021 16:13:43 +0100 Subject: [PATCH 1/7] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b8502c5..919bd5c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Forked from https://github.com/chris-belcher/electrum-personal-server + # Electrum Personal Server Electrum Personal Server aims to make using Electrum bitcoin wallet more secure From 7c7e6320cc33874fb576e7c4fb08953d6daf7ac1 Mon Sep 17 00:00:00 2001 From: Lawrence Deacon Date: Fri, 17 Sep 2021 16:19:21 +0100 Subject: [PATCH 2/7] Add listunspent method --- .../server/electrumprotocol.py | 8 ++++++++ .../server/transactionmonitor.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/electrumpersonalserver/server/electrumprotocol.py b/electrumpersonalserver/server/electrumprotocol.py index 192f6fd..7714d1c 100644 --- a/electrumpersonalserver/server/electrumprotocol.py +++ b/electrumpersonalserver/server/electrumprotocol.py @@ -256,6 +256,14 @@ def handle_query(self, query): + "hash(address) = " + scrhash) raise UnknownScripthashError(scrhash) self._send_response(query, balance) + elif method == "blockchain.scripthash.listunspent": + scrhash = query["params"][0] + utxos = self.txmonitor.get_address_utxos(scrhash) + if utxos == None: + self.logger.warning("Address history not known to server, " + + "hash(address) = " + scrhash) + raise UnknownScripthashError(scrhash) + self._send_response(query, utxos) elif method == "server.ping": self._send_response(query, None) elif method == "blockchain.headers.subscribe": diff --git a/electrumpersonalserver/server/transactionmonitor.py b/electrumpersonalserver/server/transactionmonitor.py index 961d4bd..b502160 100644 --- a/electrumpersonalserver/server/transactionmonitor.py +++ b/electrumpersonalserver/server/transactionmonitor.py @@ -4,6 +4,7 @@ import math import sys import logging +import json from decimal import Decimal from collections import defaultdict @@ -81,6 +82,21 @@ def get_address_balance(self, scrhash): return {"confirmed": confirmed_balance, "unconfirmed": unconfirmed_balance} + def get_address_utxos(self, scrhash): + history = self.get_electrum_history(scrhash) + if history == None: + return None + utxos = [] + for tx_info in history: + tx = self.rpc.call("gettransaction", [tx_info["tx_hash"]]) + txd = self.rpc.call("decoderawtransaction", [tx["hex"]]) + for index, output in enumerate(txd["vout"]): + if script_to_scripthash(output["scriptPubKey"]["hex"] + ) != scrhash: + continue + utxos.append({"tx_hash": txd["txid"], "tx_pos": index, "value": output["value"], "confirmations": tx["confirmations"]}) + return utxos + def subscribe_address(self, scrhash): if scrhash in self.address_history: self.address_history[scrhash]["subscribed"] = True From 446163563a3c46b6a2e7c160ea9c78790b8a6fe1 Mon Sep 17 00:00:00 2001 From: Lawrence Deacon Date: Mon, 27 Sep 2021 10:18:30 +0100 Subject: [PATCH 3/7] Allow import of addresses and rescan via an API method. --- electrumpersonalserver/server/common.py | 1 - .../server/electrumprotocol.py | 25 ++++++++++++++++++- .../server/transactionmonitor.py | 12 ++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/electrumpersonalserver/server/common.py b/electrumpersonalserver/server/common.py index 812b7c2..488f75b 100644 --- a/electrumpersonalserver/server/common.py +++ b/electrumpersonalserver/server/common.py @@ -303,7 +303,6 @@ def get_scriptpubkeys_to_monitor(rpc, config): break spks_to_monitor.append(spks[0]) wal.rewind_one(change) - spks_to_monitor.extend([hashes.address_to_script(addr, rpc) for addr in watch_only_addresses]) et = time.time() diff --git a/electrumpersonalserver/server/electrumprotocol.py b/electrumpersonalserver/server/electrumprotocol.py index 7714d1c..875cdab 100644 --- a/electrumpersonalserver/server/electrumprotocol.py +++ b/electrumpersonalserver/server/electrumprotocol.py @@ -7,11 +7,13 @@ import tempfile import socket from collections import defaultdict +from electrumpersonalserver.server.deterministicwallet import import_addresses from electrumpersonalserver.server.hashes import ( hash_merkle_root, get_status_electrum, - bytes_fmt + bytes_fmt, + address_to_script ) from .jsonrpc import JsonRpc, JsonRpcError from electrumpersonalserver.server.peertopeer import tor_broadcast_tx @@ -392,6 +394,7 @@ def handle_query(self, query): self._send_response(query, result) elif method == "blockchain.estimatefee": estimate = self.rpc.call("estimatesmartfee", [query["params"][0]]) + self.logger.info('estimate: ' + estimate) feerate = 0.0001 if "feerate" in estimate: feerate = estimate["feerate"] @@ -483,7 +486,27 @@ def handle_query(self, query): except JsonRpcError as e: error = {"message": repr(e)} self._send_error(query["id"], error) + elif method == "import_addresses": + addresses = query["params"][0] + rescan_height = False + if len(query["params"]) > 1: + rescan_height = query["params"][1] + if rescan_height < 0: + rescan_height = False + if len(addresses) > 0: + spks_to_monitor = [] + spks_to_monitor.extend([address_to_script(addr, self.rpc) for addr in addresses]) + self.logger.info("Importing addresses:" + ' '.join(map(str,addresses)) + "...") + import_addresses(self.rpc, spks_to_monitor, [], -1, self.logger) + self.logger.info("end") + if ( rescan_height ): + self.logger.info("Rescanning. . . for progress indicator see the bitcoin node's" + " debug.log file") + self.rpc.call("rescanblockchain", [rescan_height]) + self.logger.info("end") + self.txmonitor.build_address_history(spks_to_monitor) + self._send_response(query, { "result": "success"} ) else: + self.logger.error(method) self.logger.error("*** BUG! Not handling method: " + method + " query=" + str(query)) diff --git a/electrumpersonalserver/server/transactionmonitor.py b/electrumpersonalserver/server/transactionmonitor.py index b502160..970c8b2 100644 --- a/electrumpersonalserver/server/transactionmonitor.py +++ b/electrumpersonalserver/server/transactionmonitor.py @@ -111,7 +111,7 @@ def unsubscribe_all_addresses(self): def build_address_history(self, monitored_scriptpubkeys): logger = self.logger logger.info("Building history with " + - str(len(monitored_scriptpubkeys)) + " addresses . . .") + str(len(monitored_scriptpubkeys)) + " addresses . . . : ") st = time.time() address_history = {} for spk in monitored_scriptpubkeys: @@ -208,8 +208,14 @@ def build_address_history(self, monitored_scriptpubkeys): et = time.time() logger.info("Found " + str(count) + " txes. History built in " + str(et - st) + "sec") - self.address_history = address_history - self.unconfirmed_txes = unconfirmed_txes + if(self.address_history == None): + self.address_history=address_history + else: + self.address_history.update(address_history) + if(self.unconfirmed_txes == None): + self.unconfirmed_txes=unconfirmed_txes + else: + self.unconfirmed_txes.update(unconfirmed_txes) return True def get_input_and_output_scriptpubkeys(self, txid): From 2edecbcfbf481cb0499100c31821aab1d98b61c0 Mon Sep 17 00:00:00 2001 From: Lawrence Deacon Date: Mon, 27 Sep 2021 10:19:20 +0100 Subject: [PATCH 4/7] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 919bd5c..b8502c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Forked from https://github.com/chris-belcher/electrum-personal-server - # Electrum Personal Server Electrum Personal Server aims to make using Electrum bitcoin wallet more secure From 8fac88da348195883914b371aa77ef399882ae5f Mon Sep 17 00:00:00 2001 From: Lawrence Deacon Date: Mon, 27 Sep 2021 10:21:30 +0100 Subject: [PATCH 5/7] Update README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 919bd5c..b8502c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -Forked from https://github.com/chris-belcher/electrum-personal-server - # Electrum Personal Server Electrum Personal Server aims to make using Electrum bitcoin wallet more secure From e9bc7019d9a063eb84b483ee8527264214f86ef2 Mon Sep 17 00:00:00 2001 From: Lawrence Deacon Date: Mon, 27 Sep 2021 10:23:39 +0100 Subject: [PATCH 6/7] Revert subscribe_all_addresses log output. --- electrumpersonalserver/server/transactionmonitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electrumpersonalserver/server/transactionmonitor.py b/electrumpersonalserver/server/transactionmonitor.py index 970c8b2..244c82c 100644 --- a/electrumpersonalserver/server/transactionmonitor.py +++ b/electrumpersonalserver/server/transactionmonitor.py @@ -111,7 +111,7 @@ def unsubscribe_all_addresses(self): def build_address_history(self, monitored_scriptpubkeys): logger = self.logger logger.info("Building history with " + - str(len(monitored_scriptpubkeys)) + " addresses . . . : ") + str(len(monitored_scriptpubkeys)) + " addresses . . .") st = time.time() address_history = {} for spk in monitored_scriptpubkeys: From 343ce3a38ece89cc54620ac70515febd8e9a0d24 Mon Sep 17 00:00:00 2001 From: Tom Trevethan Date: Fri, 22 Apr 2022 17:06:01 +0100 Subject: [PATCH 7/7] added dockerfile --- Dockerfile | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6adce8a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM python +WORKDIR / +RUN git clone https://github.com/commerceblock/electrum-personal-server.git +WORKDIR /electrum-personal-server +ADD config.ini config.ini +RUN pip3 install . +CMD ["electrum-personal-server", "config.ini"] \ No newline at end of file