Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -15,8 +15,7 @@ import platform
|
||||
|
||||
try:
|
||||
import amodem.audio
|
||||
import amodem.recv
|
||||
import amodem.send
|
||||
import amodem.main
|
||||
import amodem.config
|
||||
print_error('Audio MODEM is available.')
|
||||
amodem.log.addHandler(amodem.logging.StreamHandler(sys.stderr))
|
||||
@@ -115,7 +114,7 @@ class Plugin(BasePlugin):
|
||||
with self._audio_interface() as interface:
|
||||
src = BytesIO(blob)
|
||||
dst = interface.player()
|
||||
amodem.send.main(config=self.modem_config, src=src, dst=dst)
|
||||
amodem.main.send(config=self.modem_config, src=src, dst=dst)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -132,7 +131,7 @@ class Plugin(BasePlugin):
|
||||
with self._audio_interface() as interface:
|
||||
src = interface.recorder()
|
||||
dst = BytesIO()
|
||||
amodem.recv.main(config=self.modem_config, src=src, dst=dst)
|
||||
amodem.main.recv(config=self.modem_config, src=src, dst=dst)
|
||||
return dst.getvalue()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -17,6 +17,7 @@ from electrum_gui.qt.amountedit import AmountEdit
|
||||
|
||||
EXCHANGES = ["BitcoinAverage",
|
||||
"BitcoinVenezuela",
|
||||
"BTCParalelo",
|
||||
"Bitcurex",
|
||||
"Bitmarket",
|
||||
"BitPay",
|
||||
@@ -63,6 +64,26 @@ class Exchanger(threading.Thread):
|
||||
except Exception:
|
||||
raise
|
||||
return json_resp
|
||||
|
||||
def get_json_insecure(self, site, get_string):
|
||||
""" get_json_insecure shouldn't be used in production releases
|
||||
It doesn't use SSL, and so prices could be manipulated by a middle man
|
||||
This should be used ONLY when developing plugins when you don't have a
|
||||
SSL certificate that validates against HTTPSConnection
|
||||
"""
|
||||
try:
|
||||
connection = httplib.HTTPConnection(site)
|
||||
connection.request("GET", get_string, headers={"User-Agent":"Electrum"})
|
||||
except Exception:
|
||||
raise
|
||||
resp = connection.getresponse()
|
||||
if resp.reason == httplib.responses[httplib.NOT_FOUND]:
|
||||
raise
|
||||
try:
|
||||
json_resp = json.loads(resp.read())
|
||||
except Exception:
|
||||
raise
|
||||
return json_resp
|
||||
|
||||
|
||||
def exchange(self, btc_amount, quote_currency):
|
||||
@@ -82,6 +103,7 @@ class Exchanger(threading.Thread):
|
||||
update_rates = {
|
||||
"BitcoinAverage": self.update_ba,
|
||||
"BitcoinVenezuela": self.update_bv,
|
||||
"BTCParalelo": self.update_bpl,
|
||||
"Bitcurex": self.update_bx,
|
||||
"Bitmarket": self.update_bm,
|
||||
"BitPay": self.update_bp,
|
||||
@@ -110,6 +132,9 @@ class Exchanger(threading.Thread):
|
||||
def update_cd(self):
|
||||
try:
|
||||
resp_currencies = self.get_json('api.coindesk.com', "/v1/bpi/supported-currencies.json")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing coindesk")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
|
||||
@@ -138,6 +163,9 @@ class Exchanger(threading.Thread):
|
||||
try:
|
||||
resp_rate = self.get_json('api.itbit.com', "/v1/markets/XBT" + str(current_cur) + "/ticker")
|
||||
quote_currencies[str(current_cur)] = decimal.Decimal(str(resp_rate["lastPrice"]))
|
||||
except SSLError:
|
||||
print("SSL Error when accesing itbit")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
with self.lock:
|
||||
@@ -147,6 +175,9 @@ class Exchanger(threading.Thread):
|
||||
def update_wd(self):
|
||||
try:
|
||||
winkresp = self.get_json('winkdex.com', "/api/v0/price")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing winkdex")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {"USD": 0.0}
|
||||
@@ -162,6 +193,9 @@ class Exchanger(threading.Thread):
|
||||
def update_cv(self):
|
||||
try:
|
||||
jsonresp = self.get_json('www.cavirtex.com', "/api/CAD/ticker.json")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing cavirtex")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {"CAD": 0.0}
|
||||
@@ -177,6 +211,9 @@ class Exchanger(threading.Thread):
|
||||
def update_bm(self):
|
||||
try:
|
||||
jsonresp = self.get_json('www.bitmarket.pl', "/json/BTCPLN/ticker.json")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing bitmarket")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {"PLN": 0.0}
|
||||
@@ -192,6 +229,9 @@ class Exchanger(threading.Thread):
|
||||
def update_bx(self):
|
||||
try:
|
||||
jsonresp = self.get_json('pln.bitcurex.com', "/data/ticker.json")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing bitcurex")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {"PLN": 0.0}
|
||||
@@ -207,6 +247,9 @@ class Exchanger(threading.Thread):
|
||||
def update_CNY(self):
|
||||
try:
|
||||
jsonresp = self.get_json('data.btcchina.com', "/data/ticker")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing btcchina")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {"CNY": 0.0}
|
||||
@@ -222,6 +265,9 @@ class Exchanger(threading.Thread):
|
||||
def update_bp(self):
|
||||
try:
|
||||
jsonresp = self.get_json('bitpay.com', "/api/rates")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing bitpay")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {}
|
||||
@@ -237,6 +283,9 @@ class Exchanger(threading.Thread):
|
||||
def update_cb(self):
|
||||
try:
|
||||
jsonresp = self.get_json('coinbase.com', "/api/v1/currencies/exchange_rates")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing coinbase")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
|
||||
@@ -255,6 +304,9 @@ class Exchanger(threading.Thread):
|
||||
def update_bc(self):
|
||||
try:
|
||||
jsonresp = self.get_json('blockchain.info', "/ticker")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing blockchain")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {}
|
||||
@@ -270,6 +322,9 @@ class Exchanger(threading.Thread):
|
||||
def update_lb(self):
|
||||
try:
|
||||
jsonresp = self.get_json('localbitcoins.com', "/bitcoinaverage/ticker-all-currencies/")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing localbitcoins")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {}
|
||||
@@ -285,23 +340,52 @@ class Exchanger(threading.Thread):
|
||||
|
||||
def update_bv(self):
|
||||
try:
|
||||
jsonresp = self.get_json('api.bitcoinvenezuela.com', "/")
|
||||
jsonresp = self.get_json_insecure('api.bitcoinvenezuela.com', "/")
|
||||
print("**WARNING**: update_bv is using an insecure connection, shouldn't be used on production")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing bitcoinvenezuela")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
|
||||
quote_currencies = {}
|
||||
try:
|
||||
for r in jsonresp["BTC"]:
|
||||
quote_currencies[r] = Decimal(jsonresp["BTC"][r])
|
||||
|
||||
with self.lock:
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
pass
|
||||
print ("KeyError")
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
|
||||
|
||||
def update_bpl(self):
|
||||
try:
|
||||
jsonresp = self.get_json_insecure('btcparalelo.com', "/api/price")
|
||||
print("**WARNING**: update_bpl is using an insecure connection, shouldn't be used on production")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing btcparalelo")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
||||
quote_currencies = {}
|
||||
try:
|
||||
quote_currencies = {"VEF": Decimal(jsonresp["price"])}
|
||||
with self.lock:
|
||||
self.quote_currencies = quote_currencies
|
||||
except KeyError:
|
||||
print ("KeyError")
|
||||
self.parent.set_currencies(quote_currencies)
|
||||
|
||||
def update_ba(self):
|
||||
try:
|
||||
jsonresp = self.get_json('api.bitcoinaverage.com', "/ticker/global/all")
|
||||
except SSLError:
|
||||
print("SSL Error when accesing bitcoinaverage")
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
quote_currencies = {}
|
||||
@@ -411,7 +495,6 @@ class Plugin(BasePlugin):
|
||||
|
||||
@hook
|
||||
def load_wallet(self, wallet):
|
||||
self.wallet = wallet
|
||||
tx_list = {}
|
||||
for item in self.wallet.get_tx_history(self.wallet.storage.get("current_account", None)):
|
||||
tx_hash, conf, is_mine, value, fee, balance, timestamp = item
|
||||
@@ -471,6 +554,8 @@ class Plugin(BasePlugin):
|
||||
return
|
||||
if not self.resp_hist:
|
||||
return
|
||||
if not self.wallet:
|
||||
return
|
||||
|
||||
self.win.is_edit = True
|
||||
self.win.history_list.setColumnCount(6)
|
||||
|
||||
@@ -96,6 +96,7 @@ class Plugin(BasePlugin):
|
||||
print_error("trezor: clear session")
|
||||
if self.wallet and self.wallet.client:
|
||||
self.wallet.client.clear_session()
|
||||
self.wallet.client.transport.close()
|
||||
|
||||
@hook
|
||||
def load_wallet(self, wallet):
|
||||
@@ -131,6 +132,10 @@ class Plugin(BasePlugin):
|
||||
self.wallet.trezor_sign(tx)
|
||||
except Exception as e:
|
||||
tx.error = str(e)
|
||||
@hook
|
||||
def receive_menu(self, menu, addrs):
|
||||
if not self.wallet.is_watching_only() and self.wallet.atleast_version(1, 3) and len(addrs) == 1:
|
||||
menu.addAction(_("Show on TREZOR"), lambda: self.wallet.show_address(addrs[0]))
|
||||
|
||||
def settings_widget(self, window):
|
||||
return EnterButton(_('Settings'), self.settings_dialog)
|
||||
@@ -212,15 +217,22 @@ class TrezorWallet(BIP32_HD_Wallet):
|
||||
except:
|
||||
give_error('Could not connect to your Trezor. Please verify the cable is connected and that no other app is using it.')
|
||||
self.client = QtGuiTrezorClient(self.transport)
|
||||
if (self.client.features.major_version == 1 and self.client.features.minor_version < 2) or (self.client.features.major_version == 1 and self.client.features.minor_version == 2 and self.client.features.patch_version < 1):
|
||||
give_error('Outdated Trezor firmware. Please update the firmware from https://www.mytrezor.com')
|
||||
self.client.set_tx_api(self)
|
||||
#self.client.clear_session()# TODO Doesn't work with firmware 1.1, returns proto.Failure
|
||||
self.client.bad = False
|
||||
self.device_checked = False
|
||||
self.proper_device = False
|
||||
if not self.atleast_version(1, 2, 1):
|
||||
give_error('Outdated Trezor firmware. Please update the firmware from https://www.mytrezor.com')
|
||||
return self.client
|
||||
|
||||
def compare_version(self, major, minor=0, patch=0):
|
||||
features = self.get_client().features
|
||||
return cmp([features.major_version, features.minor_version, features.patch_version], [major, minor, patch])
|
||||
|
||||
def atleast_version(self, major, minor=0, patch=0):
|
||||
return self.compare_version(major, minor, patch) >= 0
|
||||
|
||||
def address_id(self, address):
|
||||
account_id, (change, address_index) = self.get_address_index(address)
|
||||
return "44'/0'/%s'/%d/%d" % (account_id, change, address_index)
|
||||
@@ -277,6 +289,21 @@ class TrezorWallet(BIP32_HD_Wallet):
|
||||
# twd.emit(SIGNAL('trezor_done'))
|
||||
#return str(decrypted_msg)
|
||||
|
||||
def show_address(self, address):
|
||||
if not self.check_proper_device():
|
||||
give_error('Wrong device or password')
|
||||
try:
|
||||
address_path = self.address_id(address)
|
||||
address_n = self.get_client().expand_path(address_path)
|
||||
except Exception, e:
|
||||
give_error(e)
|
||||
try:
|
||||
self.get_client().get_address('Bitcoin', address_n, True)
|
||||
except Exception, e:
|
||||
give_error(e)
|
||||
finally:
|
||||
twd.emit(SIGNAL('trezor_done'))
|
||||
|
||||
def sign_message(self, address, message, password):
|
||||
if not self.check_proper_device():
|
||||
give_error('Wrong device or password')
|
||||
@@ -426,6 +453,8 @@ class TrezorQtGuiMixin(object):
|
||||
message = "Confirm transaction fee on Trezor device to continue"
|
||||
elif msg.code == 7:
|
||||
message = "Confirm message to sign on Trezor device to continue"
|
||||
elif msg.code == 10:
|
||||
message = "Confirm address on Trezor device to continue"
|
||||
else:
|
||||
message = "Check Trezor device to continue"
|
||||
twd.start(message)
|
||||
|
||||
Reference in New Issue
Block a user