tImplement blockchain.scripthash.listunspent - obelisk - Electrum server using libbitcoin as its backend HTML git clone https://git.parazyd.org/obelisk DIR Log DIR Files DIR Refs DIR README DIR LICENSE --- DIR commit 95697b92c9c29b27f006815b62dc8eb27522e2b5 DIR parent e0fd14b6b5a9282c25a2c790793f9e70b2844a33 HTML Author: parazyd <parazyd@dyne.org> Date: Fri, 9 Apr 2021 00:39:19 +0200 Implement blockchain.scripthash.listunspent Diffstat: M electrumobelisk/protocol.py | 24 +++++++++++++++++++++++- M electrumobelisk/zeromq.py | 7 +++++++ 2 files changed, 30 insertions(+), 1 deletion(-) --- DIR diff --git a/electrumobelisk/protocol.py b/electrumobelisk/protocol.py t@@ -328,7 +328,29 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902 """Method: blockchain.scripthash.listunspent Return an ordered list of UTXOs sent to a script hash. """ - return + if "params" not in query or len(query["params"]) != 1: + return {"error": "malformed request"} + + scripthash = query["params"][0] + if not is_hash256_str(scripthash): + return {"error": "invalid scripthash"} + + _ec, utxo = await self.bx.fetch_utxo(scripthash) + if _ec and _ec != 0: + self.log.debug("Got error: %s", repr(_ec)) + return {"error": "internal error"} + + # TODO: Check mempool + ret = [] + for i in utxo: + rec = i["received"] + ret.append({ + "tx_pos": rec["index"], + "value": i["value"], + "tx_hash": safe_hexlify(rec["hash"][::-1]), + "height": rec["height"], + }) + return {"result": ret} async def blockchain_scripthash_subscribe(self, writer, query): # pylint: disable=W0613 """Method: blockchain.scripthash.subscribe DIR diff --git a/electrumobelisk/zeromq.py b/electrumobelisk/zeromq.py t@@ -383,6 +383,13 @@ class Client: return error_code, functools.reduce( lambda accumulator, point: accumulator + point["value"], utxo, 0) + async def fetch_utxo(self, scripthash): + """Find UTXO for given scripthash""" + error_code, history = await self.fetch_history4(scripthash) + if error_code: + return error_code, None + return error_code, Client.__receives_without_spends(history) + async def subscribe_to_blocks(self, queue): asyncio.ensure_future(self._listen_for_blocks(queue)) return queue