Skip to content

Commit

Permalink
Fixed small issue occurring while fetching transactions (wallet) in the
Browse files Browse the repository at this point in the history
masternode view when the app was not connected to the hw device.
Removed features from the "Initialize/recover hardware wallet" wizard
that are no longer supported by the Trezor API.
Added files related to building executables of the Trezor emulator.
  • Loading branch information
Bertrand256 committed Dec 12, 2018
1 parent 468cf2e commit d12fbcc
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 70 deletions.
60 changes: 30 additions & 30 deletions dash_masternode_tool.spec
@@ -1,4 +1,5 @@
# -*- mode: python -*-
import glob
import sys
import os
import os.path
Expand All @@ -11,6 +12,7 @@ no_bits = platform.architecture()[0].replace('bit','')
version_str = ''
base_dir = os.path.dirname(os.path.realpath('__file__'))


# look for version string
with open(os.path.join(base_dir, 'version.txt')) as fptr:
for line in fptr:
Expand All @@ -19,47 +21,45 @@ with open(os.path.join(base_dir, 'version.txt')) as fptr:
version_str = parts[1].strip("'")
break

add_files = [
binary_files = []
data_files = [
('version.txt', '.')
]


def add_data_file(file: str, dest_dir: str):
global data_files
data_files.append((file, dest_dir))
print(f'Adding data file {file} to dest dir {dest_dir}')


def add_binary_file(file: str, dest_dir: str):
global bianry_files
binary_files.append((file, dest_dir))
print(f'Adding binary file {file} to dest dir {dest_dir}')


for f in os.listdir(os.path.join(base_dir, 'img')):
f_full = os.path.join(base_dir, 'img', f)
if os.path.isfile(f_full):
add_files.append(('img/' + f, '/img'))
print('adding ' + str(('img/' + f, '/img')))
else:
print('Name is not a file, skipping: ' + f)
add_data_file('img/' + f, '/img')


lib_path = next(p for p in sys.path if 'site-packages' in p)
#if os_type == 'win32':
#
# qt5_path = os.path.join(lib_path, 'PyQt5\\Qt\\bin')
# sys.path.append(qt5_path)
#
# # add file vcruntime140.dll manually, due to not including by pyinstaller
# found = False
# for p in os.environ["PATH"].split(os.pathsep):
# file_name = os.path.join(p, "vcruntime140.dll")
# if os.path.exists(file_name):
# found = True
# add_files.append((file_name, ''))
# print('Adding file ' + file_name)
# break
# if not found:
# raise Exception('File vcruntime140.dll not found in the system path.')

add_files.append( (os.path.join(lib_path, 'bitcoin/english.txt'),'/bitcoin') )
add_files.append( (os.path.join(lib_path, 'mnemonic/wordlist/english.txt'),'/mnemonic/wordlist') )
add_files.append( (os.path.join(lib_path, 'trezorlib/coins.json'),'/trezorlib') )
add_files.append( (os.path.join(lib_path, 'trezorlib/transport'),'trezorlib/transport') )
add_files.append( (os.path.join(lib_path, 'trezorlib/protocol_v1.py'),'trezorlib') )
add_files.append( (os.path.join(lib_path, 'trezorlib/protocol_v2.py'),'trezorlib') )

add_data_file(os.path.join(lib_path, 'bitcoin/english.txt'), '/bitcoin')
add_data_file(os.path.join(lib_path, 'mnemonic/wordlist/english.txt'), '/mnemonic/wordlist')
add_data_file(os.path.join(lib_path, 'trezorlib/coins.json'), '/trezorlib')
add_data_file(os.path.join(lib_path, 'trezorlib/transport'), 'trezorlib/transport')
add_data_file(os.path.join(lib_path, 'trezorlib/protocol_v1.py'), 'trezorlib')
add_data_file(os.path.join(lib_path, 'trezorlib/protocol_v2.py'), 'trezorlib')
if os_type == 'darwin':
add_binary_file('/usr/local/lib/libusb-1.0.dylib', '.')

a = Analysis(['src/dash_masternode_tool.py'],
pathex=[base_dir],
binaries=[],
datas=add_files,
binaries=binary_files,
datas=data_files,
hiddenimports=['usb1'],
hookspath=[],
runtime_hooks=[],
Expand Down
2 changes: 1 addition & 1 deletion src/about_dlg.py
Expand Up @@ -25,7 +25,7 @@ def __init__(self, parent, app_version_str):
def setupUi(self):
ui_about_dlg.Ui_AboutDlg.setupUi(self, self)
self.setWindowTitle("About")
img = QPixmap(os.path.join(self.app_config.app_path, "img/dmt.png"))
img = QPixmap(os.path.join(self.app_config.app_dir, "img/dmt.png"))
img = img.scaled(QSize(64, 64))
self.lblImage.setPixmap(img)
self.lblAppName.setText('Dash Masternode Tool ' + self.app_version_str)
Expand Down
14 changes: 8 additions & 6 deletions src/app_config.py
Expand Up @@ -12,6 +12,7 @@
import re
import copy
import shutil
import sys
import threading
import time
from io import StringIO, BytesIO
Expand Down Expand Up @@ -56,7 +57,7 @@ class AppConfig(object):
def __init__(self):
self.initialized = False
self.__deterministic_mns_enabled = None
self.app_path = '' # will be passed in the init method
self.app_dir = '' # will be passed in the init method
self.app_version = ''
QLocale.setDefault(app_utils.get_default_locale())
self.date_format = app_utils.get_default_locale().dateFormat(QLocale.ShortFormat)
Expand Down Expand Up @@ -124,14 +125,14 @@ def __init__(self):
self.fernet = None
self.log_handler = None

def init(self, app_path):
def init(self, app_dir):
""" Initialize configuration after openning the application. """
self.app_path = app_path
app_defs.APP_PATH = app_path
self.app_dir = app_dir
app_defs.APP_PATH = app_dir
app_defs.APP_IMAGE_DIR = self.get_app_img_dir()

try:
with open(os.path.join(app_path, 'version.txt')) as fptr:
with open(os.path.join(app_dir, 'version.txt')) as fptr:
lines = fptr.read().splitlines()
self.app_version = app_utils.extract_app_version(lines)
except:
Expand Down Expand Up @@ -216,6 +217,7 @@ def init(self, app_path):
if not self.app_last_version or \
app_utils.version_str_to_number(self.app_last_version) < app_utils.version_str_to_number(self.app_version):
app_cache.save_data()

self.initialized = True

def close(self):
Expand Down Expand Up @@ -1046,7 +1048,7 @@ def hw_decrypt_string(self, data_str):
return None

def get_app_img_dir(self):
return os.path.join(self.app_path, '', 'img')
return os.path.join(self.app_dir, '', 'img')

@property
def deterministic_mns_enabled(self):
Expand Down
36 changes: 21 additions & 15 deletions src/bip44_wallet.py
Expand Up @@ -94,19 +94,23 @@ def __init__(self, coin_name: str, hw_session: HwSessionInfo, db_intf: DBCache,
self.on_fetch_account_txs_feedback: Callable[[int], None] = None # args: number of txses fetched each call

def signal_account_added(self, account: Bip44AccountType):
if self.on_account_added_callback and self.__tree_id == account.tree_id and self.__tree_id is not None:
if self.on_account_added_callback and account and self.__tree_id == account.tree_id and \
self.__tree_id is not None:
self.on_account_added_callback(account)

def signal_account_data_changed(self, account: Bip44AccountType):
if self.on_account_data_changed_callback and self.__tree_id == account.tree_id and self.__tree_id is not None:
if self.on_account_data_changed_callback and account and self.__tree_id == account.tree_id and \
self.__tree_id is not None:
self.on_account_data_changed_callback(account)

def signal_account_address_added(self, account: Bip44AccountType, address: Bip44AddressType):
if self.on_account_address_added_callback and self.__tree_id == account.tree_id and self.__tree_id is not None:
if self.on_account_address_added_callback and account and self.__tree_id == account.tree_id and \
self.__tree_id is not None:
self.on_account_address_added_callback(account, address)

def signal_address_data_changed(self, account: Bip44AccountType, address: Bip44AddressType):
if self.on_address_data_changed_callback and self.__tree_id == account.tree_id and self.__tree_id is not None:
if self.on_address_data_changed_callback and account and self.__tree_id == account.tree_id and \
self.__tree_id is not None:
self.on_address_data_changed_callback(account, address)

def signal_address_loaded(self, address: Bip44AddressType):
Expand Down Expand Up @@ -434,18 +438,19 @@ def _get_account_by_id(self, id: int, db_cursor, force_reload=False) -> Bip44Acc
account = self.account_by_id.get(id)

if not account:
account = Bip44AccountType(self.get_tree_id(), id, xpub='', address_index=None, bip32_path=None)
account.read_from_db(db_cursor)
self.account_by_id[id] = account
if account.bip32_path:
self.account_by_bip32_path[account.bip32_path] = account
if self.__tree_ident:
account = Bip44AccountType(self.get_tree_id(), id, xpub='', address_index=None, bip32_path=None)
account.read_from_db(db_cursor)
self.account_by_id[id] = account
if account.bip32_path:
self.account_by_bip32_path[account.bip32_path] = account

if account.bip32_path:
account.xpub = hw_intf.get_xpub(self.hw_session, account.bip32_path)
account.evaluate_address_if_null(db_cursor, self.dash_network)
if account.bip32_path:
account.xpub = hw_intf.get_xpub(self.hw_session, account.bip32_path)
account.evaluate_address_if_null(db_cursor, self.dash_network)

self._read_account_addresses(account, db_cursor)
self.signal_account_added(account)
self._read_account_addresses(account, db_cursor)
self.signal_account_added(account)
else:
if force_reload:
account.read_from_db(db_cursor)
Expand Down Expand Up @@ -1136,7 +1141,8 @@ def _update_addr_balances(self, account: Optional[Bip44AccountType], addr_ids: L
(addr_id,))

account = self._get_account_by_id(addr_id, db_cursor, force_reload=True)
self.signal_account_data_changed(account)
if account:
self.signal_account_data_changed(account)

if account is not None and account.id not in account_ids:
# update balance/received of the account if it was inconsistent with its the balance of its child
Expand Down
12 changes: 6 additions & 6 deletions src/dash_masternode_tool.py
Expand Up @@ -24,19 +24,19 @@ def my_excepthook(type, value, tback):
sys.excepthook = my_excepthook

if getattr(sys, 'frozen', False):
app_path = base_path = sys._MEIPASS
app_dir = base_path = sys._MEIPASS
else:
app_path = os.path.dirname(__file__)
path, tail = os.path.split(app_path)
app_dir = os.path.dirname(__file__)
path, tail = os.path.split(app_dir)
if tail == 'src':
app_path = path
app_dir = path

app = qwi.QApplication(sys.argv)
ui = main_dlg.MainWindow(app_path)
ui = main_dlg.MainWindow(app_dir)
ui.show()

try:
ico_path = os.path.join(app_path, 'img', 'dmt.ico')
ico_path = os.path.join(app_dir, 'img', 'dmt.ico')
if os.path.exists(ico_path):
app_icon = QIcon(ico_path)
app.setWindowIcon(app_icon)
Expand Down
2 changes: 2 additions & 0 deletions src/initialize_hw_dlg.py
Expand Up @@ -792,6 +792,8 @@ def update_current_tab(self):
HWType.get_desc(self.hw_type))

elif self.current_step == STEP_SELECT_ACTION:
self.rbActRecoverMnemonicWords.setVisible(self.hw_type != HWType.trezor)
self.rbActRecoverHexEntropy.setVisible(self.hw_type != HWType.trezor)
if self.hw_type == HWType.ledger_nano_s:
# turn off options not applicable for ledger walltes
self.rbActRecoverWordsSafe.setDisabled(True)
Expand Down
15 changes: 12 additions & 3 deletions src/main_dlg.py
Expand Up @@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
# Author: Bertrand256
# Created on: 2017-03
import subprocess
import simplejson
import base64
import binascii
Expand Down Expand Up @@ -59,15 +60,15 @@
class MainWindow(QMainWindow, WndUtils, ui_main_dlg.Ui_MainWindow):
update_status_signal = QtCore.pyqtSignal(str, str) # signal for updating status text from inside thread

def __init__(self, app_path):
def __init__(self, app_dir):
QMainWindow.__init__(self)
WndUtils.__init__(self, None)
ui_main_dlg.Ui_MainWindow.__init__(self)

self.hw_client = None
self.finishing = False
self.config = AppConfig()
self.config.init(app_path)
self.config.init(app_dir)
WndUtils.set_app_config(self, self.config)

self.dashd_intf = DashdInterface(window=None,
Expand Down Expand Up @@ -109,6 +110,7 @@ def setupUi(self):
self.inside_setup_ui = True
self.dashd_intf.window = self
self.closeEvent = self.closeEvent
self.show_hide_trezor_emulator()
self.lblStatus1 = QtWidgets.QLabel(self)
self.lblStatus1.setAutoFillBackground(False)
self.lblStatus1.setOpenExternalLinks(True)
Expand All @@ -131,6 +133,7 @@ def setupUi(self):
self.setIcon(self.action_open_proposals_window, "thumbs-up-down.png")
self.setIcon(self.action_test_hw_connection, "hw-test.png")
self.setIcon(self.action_disconnect_hw, "hw-disconnect.png")
self.setIcon(self.action_run_trezor_emulator, "hw-emulator.png")
self.setIcon(self.action_transfer_funds_for_any_address, "wallet.png")
self.setIcon(self.action_sign_message_for_cur_mn, "sign@32px.png")
self.setIcon(self.action_hw_configuration, "hw.png")
Expand All @@ -142,6 +145,7 @@ def setupUi(self):
self.action_open_proposals_window.setIconVisibleInMenu(False)
self.action_test_hw_connection.setIconVisibleInMenu(False)
self.action_disconnect_hw.setIconVisibleInMenu(False)
self.action_run_trezor_emulator.setIconVisibleInMenu(False)
self.action_transfer_funds_for_any_address.setIconVisibleInMenu(False)
self.action_sign_message_for_cur_mn.setIconVisibleInMenu(False)
self.action_hw_configuration.setIconVisibleInMenu(False)
Expand Down Expand Up @@ -293,6 +297,10 @@ def update_config_files_mru_menu_items(self):
self.config.app_config_file_name,
self.on_config_file_mru_clear_triggered)

def show_hide_trezor_emulator(self):
enabled = False
self.action_run_trezor_emulator.setVisible(enabled)

def on_config_file_mru_action_triggered(self, file_name: str) -> None:
""" Triggered by clicking one of the subitems of the 'Open Recent' menu item. Each subitem is
related to one of recently openend configuration files.
Expand Down Expand Up @@ -1907,4 +1915,5 @@ def on_proregtx_finished(masternode: MasternodeConfig):
on_proregtx_success_callback=on_proregtx_finished)
reg_dlg.exec_()
else:
WndUtils.errorMsg('No masternode selected')
WndUtils.errorMsg('No masternode selected')

44 changes: 44 additions & 0 deletions src/trezor-t-emu.py
@@ -0,0 +1,44 @@
import os
import subprocess
import sys
import logging
import time
import threading
import PyQt5.QtWidgets as qwi


def execute_trezor_emu(emulator_base_dir: str, profile_dir: str):
env = os.environ
env['BROWSER'] = 'chromium'
env['TREZOR_PROFILE'] = profile_dir
start_sh = 'emu.sh'

try:
p = subprocess.Popen([os.path.join(emulator_base_dir, start_sh)], cwd=emulator_base_dir, env=env)
p.wait()
app.exit(0)
except Exception as e:
print(str(e))
app.exit(1)


if __name__ == '__main__':
app = qwi.QApplication(sys.argv)

if getattr(sys, 'frozen', False):
emulator_base_dir = sys._MEIPASS
emulator_bin = os.path.join(emulator_base_dir, 'micropython')
print('emulator_dir: ' + emulator_base_dir)
else:
app_dir = os.path.dirname(__file__)
path, tail = os.path.split(app_dir)
if tail == 'src':
app_dir = path
emulator_base_dir = os.path.join(app_dir, 'hardware-wallets', 'trezor-core-emu')
emulator_bin = os.path.join(emulator_base_dir, sys.platform, 'micropython')

profile_dir = os.path.join(os.path.expanduser('~'), '.dmt', 'trezor-core-emu')
t = threading.Thread(target=execute_trezor_emu, args=(emulator_base_dir, profile_dir))
t.start()

sys.exit(app.exec_())
4 changes: 2 additions & 2 deletions src/ui/ui_initialize_hw_dlg.py
Expand Up @@ -481,7 +481,7 @@ def setupUi(self, HwInitializeDlg):
self.tabFirmwareWebSources.setHorizontalHeaderItem(4, item)
item = QtWidgets.QTableWidgetItem()
self.tabFirmwareWebSources.setHorizontalHeaderItem(5, item)
self.tabFirmwareWebSources.horizontalHeader().setVisible(True)
self.tabFirmwareWebSources.horizontalHeader().setVisible(False)
self.tabFirmwareWebSources.verticalHeader().setVisible(False)
self.verticalLayout_16.addWidget(self.tabFirmwareWebSources)
self.edtFirmwareNotes = QtWidgets.QTextEdit(self.pgStepHwFirmwareList)
Expand Down Expand Up @@ -541,7 +541,7 @@ def setupUi(self, HwInitializeDlg):
self.verticalLayout.addWidget(self.widget)

self.retranslateUi(HwInitializeDlg)
self.tabSteps.setCurrentIndex(8)
self.tabSteps.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(HwInitializeDlg)

def retranslateUi(self, HwInitializeDlg):
Expand Down

0 comments on commit d12fbcc

Please sign in to comment.