Browse Source

Merge branch 'master' into btchip

283
BTChip 11 years ago
parent
commit
11961ae811
  1. 45
      gui/qt/installwizard.py
  2. 2
      gui/qt/main_window.py
  3. 8
      gui/qt/util.py
  4. 1
      icons.qrc
  5. BIN
      icons/trustedcoin.png
  6. 3
      lib/bitcoin.py
  7. 2
      lib/commands.py
  8. 1
      lib/plugins.py
  9. 2
      lib/tests/test_bitcoin.py
  10. 29
      lib/tests/test_wallet.py
  11. 10
      lib/wallet.py
  12. 91
      plugins/cosigner_pool.py
  13. 52
      plugins/trezor.py

45
gui/qt/installwizard.py

@ -33,6 +33,7 @@ class InstallWizard(QDialog):
self.network = network self.network = network
self.storage = storage self.storage = storage
self.setMinimumSize(575, 400) self.setMinimumSize(575, 400)
self.setMaximumSize(575, 400)
self.setWindowTitle('Electrum') self.setWindowTitle('Electrum')
self.connect(self, QtCore.SIGNAL('accept'), self.accept) self.connect(self, QtCore.SIGNAL('accept'), self.accept)
@ -313,16 +314,19 @@ class InstallWizard(QDialog):
return None return None
def question(self, msg, icon=None): def question(self, msg, yes_label=_('OK'), no_label=_('Cancel'), icon=None):
vbox = QVBoxLayout() vbox = QVBoxLayout()
self.set_layout(vbox) self.set_layout(vbox)
if icon: if icon:
logo = QLabel() logo = QLabel()
logo.setPixmap(icon) logo.setPixmap(icon)
vbox.addWidget(logo) vbox.addWidget(logo)
vbox.addWidget(QLabel(msg))
label = QLabel(msg)
label.setWordWrap(True)
vbox.addWidget(label)
vbox.addStretch(1) vbox.addStretch(1)
vbox.addLayout(ok_cancel_buttons(self, _('OK'))) vbox.addLayout(ok_cancel_buttons(self, yes_label, no_label))
if not self.exec_(): if not self.exec_():
return None return None
return True return True
@ -343,29 +347,6 @@ class InstallWizard(QDialog):
return run_password_dialog(self, None, self)[2] return run_password_dialog(self, None, self)[2]
def create_cold_seed(self, wallet):
from electrum.bitcoin import mnemonic_to_seed, bip32_root
msg = _('You are about to generate the cold storage seed of your wallet.') + '\n' \
+ _('For safety, you should do this on an offline computer.')
icon = QPixmap( ':icons/cold_seed.png').scaledToWidth(56)
if not self.question(msg, icon):
return
cold_seed = wallet.make_seed()
if not self.show_seed(cold_seed, 'cold'):
return
if not self.verify_seed(cold_seed, 'cold'):
return
hex_seed = mnemonic_to_seed(cold_seed,'').encode('hex')
xpriv, xpub = bip32_root(hex_seed)
wallet.add_master_public_key('cold/', xpub)
msg = _('Your master public key was saved in your wallet file.') + '\n'\
+ _('Your cold seed must be stored on paper; it is not in the wallet file.')+ '\n\n' \
+ _('This program is about to close itself.') + '\n'\
+ _('You will need to reopen your wallet on an online computer, in order to complete the creation of your wallet')
self.show_message(msg)
@ -429,14 +410,13 @@ class InstallWizard(QDialog):
return return
self.waiting_dialog(wallet.synchronize) self.waiting_dialog(wallet.synchronize)
elif action == 'create_cold_seed':
self.create_cold_seed(wallet)
return
else: else:
r = run_hook('install_wizard_action', self, wallet, action) f = run_hook('get_wizard_action', self, wallet, action)
if not r: if not f:
raise BaseException('unknown wizard action', action) raise BaseException('unknown wizard action', action)
r = f(wallet, self)
if not r:
return
# next action # next action
action = wallet.get_action() action = wallet.get_action()
@ -558,6 +538,7 @@ class InstallWizard(QDialog):
wallet.create_main_account(password) wallet.create_main_account(password)
else: else:
self.storage.put('wallet_type', t)
wallet = run_hook('installwizard_restore', self, self.storage) wallet = run_hook('installwizard_restore', self, self.storage)
if not wallet: if not wallet:
return return

2
gui/qt/main_window.py

@ -1988,6 +1988,7 @@ class ElectrumWindow(QMainWindow):
decrypted = self.wallet.decrypt_message(str(pubkey_e.text()), str(encrypted_e.toPlainText()), password) decrypted = self.wallet.decrypt_message(str(pubkey_e.text()), str(encrypted_e.toPlainText()), password)
message_e.setText(decrypted) message_e.setText(decrypted)
except Exception as e: except Exception as e:
traceback.print_exc(file=sys.stdout)
self.show_message(str(e)) self.show_message(str(e))
@ -1998,6 +1999,7 @@ class ElectrumWindow(QMainWindow):
encrypted = bitcoin.encrypt_message(message, str(pubkey_e.text())) encrypted = bitcoin.encrypt_message(message, str(pubkey_e.text()))
encrypted_e.setText(encrypted) encrypted_e.setText(encrypted)
except Exception as e: except Exception as e:
traceback.print_exc(file=sys.stdout)
self.show_message(str(e)) self.show_message(str(e))

8
gui/qt/util.py

@ -94,10 +94,10 @@ def close_button(dialog, label=_("Close") ):
b.setDefault(True) b.setDefault(True)
return hbox return hbox
def ok_cancel_buttons2(dialog, ok_label=_("OK") ): def ok_cancel_buttons2(dialog, ok_label=_("OK"), cancel_label=_('Cancel')):
hbox = QHBoxLayout() hbox = QHBoxLayout()
hbox.addStretch(1) hbox.addStretch(1)
b = QPushButton(_("Cancel")) b = QPushButton(cancel_label)
hbox.addWidget(b) hbox.addWidget(b)
b.clicked.connect(dialog.reject) b.clicked.connect(dialog.reject)
b = QPushButton(ok_label) b = QPushButton(ok_label)
@ -106,8 +106,8 @@ def ok_cancel_buttons2(dialog, ok_label=_("OK") ):
b.setDefault(True) b.setDefault(True)
return hbox, b return hbox, b
def ok_cancel_buttons(dialog, ok_label=_("OK") ): def ok_cancel_buttons(dialog, ok_label=_("OK"), cancel_label=_('Cancel')):
hbox, b = ok_cancel_buttons2(dialog, ok_label) hbox, b = ok_cancel_buttons2(dialog, ok_label, cancel_label)
return hbox return hbox
def line_dialog(parent, title, label, ok_label, default=None): def line_dialog(parent, title, label, ok_label, default=None):

1
icons.qrc

@ -25,5 +25,6 @@
<file>icons/network.png</file> <file>icons/network.png</file>
<file>icons/dark_background.png</file> <file>icons/dark_background.png</file>
<file>icons/qrcode.png</file> <file>icons/qrcode.png</file>
<file>icons/trustedcoin.png</file>
</qresource> </qresource>
</RCC> </RCC>

BIN
icons/trustedcoin.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

3
lib/bitcoin.py

@ -706,10 +706,9 @@ def xpub_from_xprv(xprv, testnet=False):
return EncodeBase58Check(xpub) return EncodeBase58Check(xpub)
def bip32_root(mnemonic_seed, testnet=False): def bip32_root(seed, testnet=False):
import hmac import hmac
header_pub, header_priv = _get_headers(testnet) header_pub, header_priv = _get_headers(testnet)
seed = mnemonic_to_seed(mnemonic_seed,'')
I = hmac.new("Bitcoin seed", seed, hashlib.sha512).digest() I = hmac.new("Bitcoin seed", seed, hashlib.sha512).digest()
master_k = I[0:32] master_k = I[0:32]
master_c = I[32:] master_c = I[32:]

2
lib/commands.py

@ -320,7 +320,7 @@ class Commands:
label, is_default_label = self.wallet.get_label(tx_hash) label, is_default_label = self.wallet.get_label(tx_hash)
out.append({'txid':tx_hash, 'date':"%16s"%time_str, 'label':label, 'value':format_satoshis(value)}) out.append({'txid':tx_hash, 'date':"%16s"%time_str, 'label':label, 'value':format_satoshis(value), 'confirmations':conf})
return out return out
def setlabel(self, key, label): def setlabel(self, key, label):

1
lib/plugins.py

@ -50,6 +50,7 @@ def run_hook(name, *args):
except Exception: except Exception:
print_error("Plugin error") print_error("Plugin error")
traceback.print_exc(file=sys.stdout) traceback.print_exc(file=sys.stdout)
r = False
if r: if r:
results.append(r) results.append(r)

2
lib/tests/test_bitcoin.py

@ -68,7 +68,7 @@ class Test_bitcoin(unittest.TestCase):
assert xprv == "tprv8jTo9vZtZTSiTo6BBDjeQDgLEaipWPsrhYsQpZYoqqJNPKbCyDewkHJZhkoSHiWYCUf1Gm4TFzQxcG4D6s1J9Hsn4whDK7QYyHHokJeUuac" assert xprv == "tprv8jTo9vZtZTSiTo6BBDjeQDgLEaipWPsrhYsQpZYoqqJNPKbCyDewkHJZhkoSHiWYCUf1Gm4TFzQxcG4D6s1J9Hsn4whDK7QYyHHokJeUuac"
def _do_test_bip32(self, seed, sequence, testnet): def _do_test_bip32(self, seed, sequence, testnet):
xprv, xpub = bip32_root(seed, testnet) xprv, xpub = bip32_root(seed.decode('hex'), testnet)
assert sequence[0:2] == "m/" assert sequence[0:2] == "m/"
path = 'm' path = 'm'
sequence = sequence[2:] sequence = sequence[2:]

29
lib/tests/test_wallet.py

@ -3,6 +3,7 @@ import tempfile
import sys import sys
import unittest import unittest
import os import os
import json
from StringIO import StringIO from StringIO import StringIO
from lib.wallet import WalletStorage, NewWallet from lib.wallet import WalletStorage, NewWallet
@ -97,20 +98,15 @@ class TestWalletStorage(WalletTestCase):
contents = "" contents = ""
with open(path, "r") as f: with open(path, "r") as f:
contents = f.read() contents = f.read()
self.assertEqual(repr(some_dict), contents) self.assertEqual(some_dict, json.loads(contents))
class TestNewWallet(WalletTestCase): class TestNewWallet(WalletTestCase):
seed_text = "The seed will sprout and grow up tall." seed_text = "travel nowhere air position hill peace suffer parent beautiful rise blood power home crumble teach"
password = "secret" password = "secret"
master_xpub = "xpub661MyMwAqRbcGEop5Rnp68oX1ikeFNVMtx1utwXZGRKMmeXVxwBM5UzkwU9nGB1EofZekLDRfi1w5F9P7Vac3PEuWdWHr2gHLW8vp5YyKJ1"
master_xpriv = "xprv9s21ZrQH143K3kjLyQFoizrnTgv9qumWXj6K6Z7wi5nNtrCMRPs6XggH6Bbgz9CUgPJnZnV74yUdRSr8qWVELr9QQTgU5aNL33ViMyD9nhs"
first_account_name = "account1" first_account_name = "account1"
first_account_first_address = "1Jv9pLCJ4Sqr7aDYLGX5QhET4ps5qRcB9V"
first_account_second_address = "14n9EsZsgTTc4eC4TxeP1ccP8bXgwxPMmL"
import_private_key = "L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW" import_private_key = "L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW"
import_key_address = "15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma" import_key_address = "15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma"
@ -131,7 +127,8 @@ class TestNewWallet(WalletTestCase):
# in setUp() # in setUp()
new_dir = tempfile.mkdtemp() new_dir = tempfile.mkdtemp()
config = FakeConfig(new_dir) config = FakeConfig(new_dir)
wallet = NewWallet(config) storage = WalletStorage(config)
wallet = NewWallet(storage)
self.assertTrue(wallet.is_watching_only()) self.assertTrue(wallet.is_watching_only())
shutil.rmtree(new_dir) # Don't leave useless stuff in /tmp shutil.rmtree(new_dir) # Don't leave useless stuff in /tmp
@ -142,22 +139,6 @@ class TestNewWallet(WalletTestCase):
self.assertEqual(self.wallet.get_seed(self.password), self.seed_text) self.assertEqual(self.wallet.get_seed(self.password), self.seed_text)
self.assertEqual(0, len(self.wallet.addresses())) self.assertEqual(0, len(self.wallet.addresses()))
def test_add_account(self):
self.wallet.create_account(self.first_account_name, self.password)
self.assertEqual(1, len(self.wallet.addresses()))
self.assertIn(self.first_account_first_address,
self.wallet.addresses())
def test_add_account_add_address(self):
self.wallet.create_account(self.first_account_name, self.password)
self.wallet.synchronizer = FakeSynchronizer()
self.wallet.create_new_address()
self.assertEqual(2, len(self.wallet.addresses()))
self.assertIn(self.first_account_first_address,
self.wallet.addresses())
self.assertIn(self.first_account_second_address,
self.wallet.addresses())
def test_key_import(self): def test_key_import(self):
# Wallets have no imported keys by default. # Wallets have no imported keys by default.

10
lib/wallet.py

@ -1385,7 +1385,7 @@ class BIP39_Wallet(BIP32_Wallet):
def create_master_keys(self, password): def create_master_keys(self, password):
seed = self.get_seed(password) seed = self.get_seed(password)
xprv, xpub = bip32_root(seed) xprv, xpub = bip32_root(mnemonic_to_seed(seed,''))
xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation)
self.add_master_public_key(self.root_name, xpub) self.add_master_public_key(self.root_name, xpub)
self.add_master_private_key(self.root_name, xprv, password) self.add_master_private_key(self.root_name, xprv, password)
@ -1459,11 +1459,17 @@ class Wallet_2of2(BIP39_Wallet):
def add_cosigner_seed(self, seed, name, password): def add_cosigner_seed(self, seed, name, password):
# we don't store the seed, only the master xpriv # we don't store the seed, only the master xpriv
xprv, xpub = bip32_root(seed) xprv, xpub = bip32_root(mnemonic_to_seed(seed,''))
xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation) xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation)
self.add_master_public_key(name, xpub) self.add_master_public_key(name, xpub)
self.add_master_private_key(name, xprv, password) self.add_master_private_key(name, xprv, password)
def add_cosigner_xpub(self, seed, name):
# store only master xpub
xprv, xpub = bip32_root(mnemonic_to_seed(seed,''))
xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation)
self.add_master_public_key(name, xpub)
class Wallet_2of3(Wallet_2of2): class Wallet_2of3(Wallet_2of2):

91
plugins/cosigner_pool.py

@ -45,42 +45,36 @@ class Listener(threading.Thread):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.daemon = True self.daemon = True
self.parent = parent self.parent = parent
self.key = None self.keyname = None
self.keyhash = None
self.is_running = False self.is_running = False
self.message = None self.message = None
self.delete = False
def set_key(self, key): def set_key(self, keyname, keyhash):
self.key = key self.keyname = keyname
self.keyhash = keyhash
def clear(self): def clear(self):
self.delete = True server.delete(self.keyhash)
self.message = None
def run(self): def run(self):
self.is_running = True self.is_running = True
while self.is_running: while self.is_running:
if not self.keyhash:
if not self.key:
time.sleep(2) time.sleep(2)
continue continue
if not self.message: if not self.message:
try: try:
self.message = server.get(self.key) self.message = server.get(self.keyhash)
except Exception as e: except Exception as e:
util.print_error("cannot contact cosigner pool") util.print_error("cannot contact cosigner pool")
time.sleep(30) time.sleep(30)
continue continue
if self.message: if self.message:
self.parent.win.emit(SIGNAL("cosigner:receive")) self.parent.win.emit(SIGNAL("cosigner:receive"))
else: # poll every 30 seconds
if self.delete:
# save it to disk
server.delete(self.key)
self.message = None
self.delete = False
time.sleep(30) time.sleep(30)
@ -109,21 +103,25 @@ class Plugin(BasePlugin):
self.load_wallet(self.win.wallet) self.load_wallet(self.win.wallet)
return True return True
def is_available(self):
if self.wallet is None:
return True
return self.wallet.wallet_type in ['2of2', '2of3']
def load_wallet(self, wallet): def load_wallet(self, wallet):
self.wallet = wallet self.wallet = wallet
if not self.is_available():
return
mpk = self.wallet.get_master_public_keys() mpk = self.wallet.get_master_public_keys()
self.cosigner_list = []
self.cold = mpk.get('x2') for key, xpub in mpk.items():
if self.cold: keyname = key + '/' # fixme
self.cold_K = bitcoin.deserialize_xkey(self.cold)[-1].encode('hex') K = bitcoin.deserialize_xkey(xpub)[-1].encode('hex')
self.cold_hash = bitcoin.Hash(self.cold_K).encode('hex') _hash = bitcoin.Hash(K).encode('hex')
if self.wallet.master_private_keys.get(keyname):
self.hot = mpk.get('x1') self.listener.set_key(keyname, _hash)
if self.hot: else:
self.hot_K = bitcoin.deserialize_xkey(self.hot)[-1].encode('hex') self.cosigner_list.append((xpub, K, _hash))
self.hot_hash = bitcoin.Hash(self.hot_K).encode('hex')
self.listener.set_key(self.hot_hash)
def transaction_dialog(self, d): def transaction_dialog(self, d):
self.send_button = b = QPushButton(_("Send to cosigner")) self.send_button = b = QPushButton(_("Send to cosigner"))
@ -131,18 +129,18 @@ class Plugin(BasePlugin):
d.buttons.insertWidget(2, b) d.buttons.insertWidget(2, b)
self.transaction_dialog_update(d) self.transaction_dialog_update(d)
def transaction_dialog_update(self, d): def transaction_dialog_update(self, d):
if d.tx.is_complete(): if d.tx.is_complete():
self.send_button.hide() self.send_button.hide()
return return
if self.cosigner_can_sign(d.tx): for xpub, K, _hash in self.cosigner_list:
if self.cosigner_can_sign(d.tx, xpub):
self.send_button.show() self.send_button.show()
break
else: else:
self.send_button.hide() self.send_button.hide()
def cosigner_can_sign(self, tx, cosigner_xpub):
def cosigner_can_sign(self, tx):
from electrum.transaction import x_to_xpub from electrum.transaction import x_to_xpub
xpub_set = set([]) xpub_set = set([])
for txin in tx.inputs: for txin in tx.inputs:
@ -151,24 +149,21 @@ class Plugin(BasePlugin):
if xpub: if xpub:
xpub_set.add(xpub) xpub_set.add(xpub)
return self.cold in xpub_set return cosigner_xpub in xpub_set
def do_send(self, tx): def do_send(self, tx):
if not self.cosigner_can_sign(tx): for xpub, K, _hash in self.cosigner_list:
return if not self.cosigner_can_sign(tx, xpub):
continue
message = bitcoin.encrypt_message(tx.raw, self.cold_K) message = bitcoin.encrypt_message(tx.raw, K)
try: try:
server.put(self.cold_hash, message) server.put(_hash, message)
self.win.show_message("Your transaction was sent to the cosigning pool.\nOpen your cosigner wallet to retrieve it.")
except Exception as e: except Exception as e:
self.win.show_message(str(e)) self.win.show_message(str(e))
return
self.win.show_message("Your transaction was sent to the cosigning pool.\nOpen your cosigner wallet to retrieve it.")
def on_receive(self): def on_receive(self):
if self.wallet.use_encryption: if self.wallet.use_encryption:
password = self.win.password_dialog('An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.') password = self.win.password_dialog('An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.')
if not password: if not password:
@ -177,11 +172,12 @@ class Plugin(BasePlugin):
password = None password = None
message = self.listener.message message = self.listener.message
xpriv = self.wallet.get_master_private_key('x1/', password) key = self.listener.keyname
if not xpriv: xprv = self.wallet.get_master_private_key(key, password)
if not xprv:
return return
try: try:
k = bitcoin.deserialize_xkey(xpriv)[-1].encode('hex') k = bitcoin.deserialize_xkey(xprv)[-1].encode('hex')
EC = bitcoin.EC_KEY(k.decode('hex')) EC = bitcoin.EC_KEY(k.decode('hex'))
message = EC.decrypt_message(message) message = EC.decrypt_message(message)
except Exception as e: except Exception as e:
@ -190,7 +186,6 @@ class Plugin(BasePlugin):
return return
self.listener.clear() self.listener.clear()
tx = transaction.Transaction.deserialize(message) tx = transaction.Transaction.deserialize(message)
self.win.show_transaction(tx) self.win.show_transaction(tx)

52
plugins/trezor.py

@ -1,4 +1,4 @@
from PyQt4.Qt import QMessageBox, QDialog, QVBoxLayout, QLabel, QThread, SIGNAL from PyQt4.Qt import QMessageBox, QDialog, QVBoxLayout, QLabel, QThread, SIGNAL, QGridLayout, QInputDialog, QPushButton
import PyQt4.QtCore as QtCore import PyQt4.QtCore as QtCore
from binascii import unhexlify from binascii import unhexlify
from struct import pack from struct import pack
@ -7,7 +7,7 @@ from time import sleep
from base64 import b64encode, b64decode from base64 import b64encode, b64decode
from electrum_gui.qt.password_dialog import make_password_dialog, run_password_dialog from electrum_gui.qt.password_dialog import make_password_dialog, run_password_dialog
from electrum_gui.qt.util import ok_cancel_buttons from electrum_gui.qt.util import ok_cancel_buttons, EnterButton
from electrum.account import BIP32_Account from electrum.account import BIP32_Account
from electrum.bitcoin import EncodeBase58Check, public_key_to_bc_address, bc_address_to_hash_160 from electrum.bitcoin import EncodeBase58Check, public_key_to_bc_address, bc_address_to_hash_160
from electrum.i18n import _ from electrum.i18n import _
@ -43,6 +43,7 @@ class Plugin(BasePlugin):
def __init__(self, gui, name): def __init__(self, gui, name):
BasePlugin.__init__(self, gui, name) BasePlugin.__init__(self, gui, name)
self._is_available = self._init() self._is_available = self._init()
self._requires_settings = True
self.wallet = None self.wallet = None
def _init(self): def _init(self):
@ -55,6 +56,9 @@ class Plugin(BasePlugin):
return True return True
return False return False
def requires_settings(self):
return self._requires_settings
def set_enabled(self, enabled): def set_enabled(self, enabled):
self.wallet.storage.put('use_' + self.name, enabled) self.wallet.storage.put('use_' + self.name, enabled)
@ -77,6 +81,8 @@ class Plugin(BasePlugin):
wallet_types.append(('trezor', _("Trezor wallet"), TrezorWallet)) wallet_types.append(('trezor', _("Trezor wallet"), TrezorWallet))
def installwizard_restore(self, wizard, storage): def installwizard_restore(self, wizard, storage):
if storage.get('wallet_type') != 'trezor':
return
wallet = TrezorWallet(storage) wallet = TrezorWallet(storage)
try: try:
wallet.create_main_account(None) wallet.create_main_account(None)
@ -91,6 +97,41 @@ class Plugin(BasePlugin):
except Exception as e: except Exception as e:
tx.error = str(e) tx.error = str(e)
def settings_widget(self, window):
return EnterButton(_('Settings'), self.settings_dialog)
def settings_dialog(self):
get_label = lambda: self.wallet.get_client().features.label
update_label = lambda: current_label_label.setText("Label: %s" % get_label())
d = QDialog()
layout = QGridLayout(d)
layout.addWidget(QLabel("Trezor Options"),0,0)
layout.addWidget(QLabel("ID:"),1,0)
layout.addWidget(QLabel(" %s" % self.wallet.get_client().get_device_id()),1,1)
def modify_label():
response = QInputDialog().getText(None, "Set New Trezor Label", "New Trezor Label: (upon submission confirm on Trezor)")
if not response[1]:
return
new_label = str(response[0])
twd.start("Please confirm label change on Trezor")
status = self.wallet.get_client().apply_settings(label=new_label)
twd.stop()
update_label()
current_label_label = QLabel()
update_label()
change_label_button = QPushButton("Modify")
change_label_button.clicked.connect(modify_label)
layout.addWidget(current_label_label,3,0)
layout.addWidget(change_label_button,3,1)
if d.exec_():
return True
else:
return False
class TrezorWallet(NewWallet): class TrezorWallet(NewWallet):
wallet_type = 'trezor' wallet_type = 'trezor'
@ -138,7 +179,7 @@ class TrezorWallet(NewWallet):
def address_id(self, address): def address_id(self, address):
account_id, (change, address_index) = self.get_address_index(address) account_id, (change, address_index) = self.get_address_index(address)
return "%s/%d/%d" % (account_id, change, address_index) return "44'/0'/%s'/%d/%d" % (account_id, change, address_index)
def create_main_account(self, password): def create_main_account(self, password):
self.create_account('Main account', None) #name, empty password self.create_account('Main account', None) #name, empty password
@ -167,12 +208,9 @@ class TrezorWallet(NewWallet):
pass pass
def decrypt_message(self, pubkey, message, password): def decrypt_message(self, pubkey, message, password):
try:
address = public_key_to_bc_address(pubkey.decode('hex')) address = public_key_to_bc_address(pubkey.decode('hex'))
address_path = self.address_id(address) address_path = self.address_id(address)
address_n = self.get_client().expand_path(address_path) address_n = self.get_client().expand_path(address_path)
except Exception, e:
raise e
try: try:
decrypted_msg = self.get_client().decrypt_message(address_n, b64decode(message)) decrypted_msg = self.get_client().decrypt_message(address_n, b64decode(message))
except Exception, e: except Exception, e:
@ -182,6 +220,8 @@ class TrezorWallet(NewWallet):
return str(decrypted_msg) return str(decrypted_msg)
def sign_message(self, address, message, password): def sign_message(self, address, message, password):
if not self.check_proper_device():
give_error('Wrong device or password')
try: try:
address_path = self.address_id(address) address_path = self.address_id(address)
address_n = self.get_client().expand_path(address_path) address_n = self.get_client().expand_path(address_path)

Loading…
Cancel
Save