# -*- coding: utf-8 -*- # Copyright (c) 2019 tecnovert # Distributed under the MIT software license, see the accompanying # file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php. import urllib.request import json class Explorer(): def __init__(self, swapclient, coin_type, base_url): self.swapclient = swapclient self.coin_type = coin_type self.base_url = base_url self.log = self.swapclient.log self.coin_settings = self.swapclient.coin_clients[self.coin_type] def readURL(self, url): self.log.debug('Explorer url: {}'.format(url)) headers = {'User-Agent': 'Mozilla/5.0'} req = urllib.request.Request(url, headers=headers) return urllib.request.urlopen(req).read() class ExplorerInsight(Explorer): def getChainHeight(self): return json.loads(self.readURL(self.base_url + '/sync'))['blockChainHeight'] def getBlock(self, block_hash): data = json.loads(self.readURL(self.base_url + '/block/{}'.format(block_hash))) return data def getTransaction(self, txid): data = json.loads(self.readURL(self.base_url + '/tx/{}'.format(txid))) return data def getBalance(self, address): data = json.loads(self.readURL(self.base_url + '/addr/{}/balance'.format(address))) return data def lookupUnspentByAddress(self, address): data = json.loads(self.readURL(self.base_url + '/addr/{}/utxo'.format(address))) rv = [] for utxo in data: rv.append({ 'txid': utxo['txid'], 'index': utxo['vout'], 'height': utxo['height'], 'n_conf': utxo['confirmations'], 'value': utxo['satoshis'], }) return rv class ExplorerBitAps(Explorer): def getChainHeight(self): return json.loads(self.readURL(self.base_url + '/block/last'))['data']['block']['height'] def getBlock(self, block_hash): data = json.loads(self.readURL(self.base_url + '/block/{}'.format(block_hash))) return data def getTransaction(self, txid): data = json.loads(self.readURL(self.base_url + '/transaction/{}'.format(txid))) return data def getBalance(self, address): data = json.loads(self.readURL(self.base_url + '/address/state/' + address)) return data['data']['balance'] def lookupUnspentByAddress(self, address): # Can't get unspents return only if exactly one transaction exists data = json.loads(self.readURL(self.base_url + '/address/transactions/' + address)) try: assert(data['data']['list'] == 1) except Exception as ex: self.log.debug('Explorer error: {}'.format(str(ex))) return None tx = data['data']['list'][0] tx_data = json.loads(self.readURL(self.base_url + '/transaction/{}'.format(tx['txId'])))['data'] for i, vout in tx_data['vOut'].items(): if vout['address'] == address: return [{ 'txid': tx_data['txId'], 'index': int(i), 'height': tx_data['blockHeight'], 'n_conf': tx_data['confirmations'], 'value': vout['value'], }] class ExplorerChainz(Explorer): def getChainHeight(self): return int(self.readURL(self.base_url + '?q=getblockcount')) def lookupUnspentByAddress(self, address): chain_height = self.getChainHeight() self.log.debug('[rm] chain_height %d', chain_height)