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 dcbbf60f42b0477e38b868bcefe37948f33e7a37
parent 9119d0d0d13b21cb355280b003e408ffbb68cbee
Author: chris-belcher <chris-belcher@users.noreply.github.com>
Date:   Wed, 14 Nov 2018 14:37:22 +0000

Implement blockchain.scripthash.get_balance method

Issue #68 is a report that this method is sometimes used by
Electrum wallet version 3.2.3. As with similar methods in
Electrum Personal Server it only works with addresses for
which the server has been configured to know about.

Diffstat:
Melectrumpersonalserver/server/common.py | 11++++++++++-
Melectrumpersonalserver/server/transactionmonitor.py | 29+++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/electrumpersonalserver/server/common.py b/electrumpersonalserver/server/common.py @@ -170,6 +170,14 @@ def handle_query(sock, line, rpc, txmonitor): logger.warning("Address history not known to server, " + "hash(address) = " + scrhash) send_response(sock, query, history) + elif method == "blockchain.scripthash.get_balance": + scrhash = query["params"][0] + balance = txmonitor.get_address_balance(scrhash) + if balance == None: + logger.warning("Address history not known to server, " + + "hash(address) = " + scrhash) + balance = {"confirmed": 0, "unconfirmed": 0} + send_response(sock, query, balance) elif method == "server.ping": send_response(sock, query, None) elif method == "blockchain.headers.subscribe": @@ -314,7 +322,8 @@ def handle_query(sock, line, rpc, txmonitor): result = txid else: core_proof = rpc.call("gettxoutproof", [[txid], blockhash]) - electrum_proof = merkleproof.convert_core_to_electrum_merkle_proof( + electrum_proof =\ + merkleproof.convert_core_to_electrum_merkle_proof( core_proof) result = {"tx_hash": txid, "merkle": electrum_proof["merkle"]} send_response(sock, query, result) diff --git a/electrumpersonalserver/server/transactionmonitor.py b/electrumpersonalserver/server/transactionmonitor.py @@ -76,6 +76,35 @@ class TransactionMonitor(object): else: return None + def get_address_balance(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[txd["txid"] + ":" + str(index)] = (output["value"], + tx["confirmations"]) + for inputt in txd["vin"]: + outpoint = inputt["txid"] + ":" + str(inputt["vout"]) + if outpoint in utxos: + del utxos[outpoint] + confirmed_balance = 0 + unconfirmed_balance = 0 + for utxo in utxos.values(): + value = int(Decimal(utxo[0]) * Decimal(1e8)) + if utxo[1] > 0: + confirmed_balance += value + else: + unconfirmed_balance += value + return {"confirmed": confirmed_balance, "unconfirmed": + unconfirmed_balance} + def subscribe_address(self, scrhash): if scrhash in self.address_history: self.address_history[scrhash]["subscribed"] = True