From 2f6629bb71cdc19a915b634985bbb54ebbe35777 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Wed, 25 May 2022 11:35:08 -0500 Subject: [PATCH 1/4] Bugfix for manual seed entry after scanning psbt --- src/seedsigner/views/psbt_views.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index 1b8da55d..5a3cbb06 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -32,7 +32,8 @@ class PSBTSelectSeedView(View): seeds = self.controller.storage.seeds SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE) - ENTER_WORDS = "Enter 12/24 words" + TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) + TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) button_data = [] for seed in seeds: button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK)) @@ -45,7 +46,8 @@ class PSBTSelectSeedView(View): pass button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue")) button_data.append(SCAN_SEED) - button_data.append(ENTER_WORDS) + button_data.append(TYPE_12WORD) + button_data.append(TYPE_24WORD) selected_menu_num = ButtonListScreen( title="Select Signer", @@ -68,8 +70,12 @@ class PSBTSelectSeedView(View): from seedsigner.views.scan_views import ScanView return Destination(ScanView) - elif button_data[selected_menu_num] == ENTER_WORDS: + elif button_data[selected_menu_num] in [TYPE_12WORD, TYPE_24WORD]: from seedsigner.views.seed_views import SeedMnemonicEntryView + if button_data[selected_menu_num] == TYPE_12WORD: + self.controller.storage.init_pending_mnemonic(12) + else: + self.controller.storage.init_pending_mnemonic(24) return Destination(SeedMnemonicEntryView) From e7d09a1c3b8db43144ae31ad63aa5179a783c333 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Wed, 25 May 2022 11:45:22 -0500 Subject: [PATCH 2/4] Fix for single sig addr verification --- src/seedsigner/views/psbt_views.py | 4 ++-- src/seedsigner/views/seed_views.py | 25 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index 5a3cbb06..5e2149cc 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -73,9 +73,9 @@ class PSBTSelectSeedView(View): elif button_data[selected_menu_num] in [TYPE_12WORD, TYPE_24WORD]: from seedsigner.views.seed_views import SeedMnemonicEntryView if button_data[selected_menu_num] == TYPE_12WORD: - self.controller.storage.init_pending_mnemonic(12) + self.controller.storage.init_pending_mnemonic(num_words=12) else: - self.controller.storage.init_pending_mnemonic(24) + self.controller.storage.init_pending_mnemonic(num_words=24) return Destination(SeedMnemonicEntryView) diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 9fb12d43..9e580456 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -73,13 +73,13 @@ class SeedsMenuView(View): class LoadSeedView(View): def run(self): SEED_QR = (" Scan a SeedQR", FontAwesomeIconConstants.QRCODE) - TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) + TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) CREATE = (" Create a seed", FontAwesomeIconConstants.PLUS) button_data=[ SEED_QR, - TYPE_24WORD, TYPE_12WORD, + TYPE_24WORD, CREATE, ] @@ -96,14 +96,14 @@ class LoadSeedView(View): from .scan_views import ScanView return Destination(ScanView) - elif button_data[selected_menu_num] == TYPE_24WORD: - self.controller.storage.init_pending_mnemonic(num_words=24) - return Destination(SeedMnemonicEntryView) - elif button_data[selected_menu_num] == TYPE_12WORD: self.controller.storage.init_pending_mnemonic(num_words=12) return Destination(SeedMnemonicEntryView) + elif button_data[selected_menu_num] == TYPE_24WORD: + self.controller.storage.init_pending_mnemonic(num_words=24) + return Destination(SeedMnemonicEntryView) + elif button_data[selected_menu_num] == CREATE: from .tools_views import ToolsMenuView return Destination(ToolsMenuView) @@ -1314,7 +1314,8 @@ class SeedSingleSigAddressVerificationSelectSeedView(View): seeds = self.controller.storage.seeds SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE) - ENTER_WORDS = "Enter 12/24 words" + TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD) + TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD) button_data = [] text = "Load the seed to verify" @@ -1330,7 +1331,8 @@ class SeedSingleSigAddressVerificationSelectSeedView(View): text = "Select seed to verify" button_data.append(SCAN_SEED) - button_data.append(ENTER_WORDS) + button_data.append(TYPE_12WORD) + button_data.append(TYPE_24WORD) selected_menu_num = seed_screens.SeedSingleSigAddressVerificationSelectSeedScreen( title="Verify Address", @@ -1357,7 +1359,12 @@ class SeedSingleSigAddressVerificationSelectSeedView(View): from seedsigner.views.scan_views import ScanView return Destination(ScanView) - elif button_data[selected_menu_num] == ENTER_WORDS: + elif button_data[selected_menu_num] in [TYPE_12WORD, TYPE_24WORD]: + from seedsigner.views.seed_views import SeedMnemonicEntryView + if button_data[selected_menu_num] == TYPE_12WORD: + self.controller.storage.init_pending_mnemonic(num_words=12) + else: + self.controller.storage.init_pending_mnemonic(num_words=24) return Destination(SeedMnemonicEntryView) From 3afeeda11c83c04410c4ae5aabfa37a147564413 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Thu, 26 May 2022 08:09:03 -0500 Subject: [PATCH 3/4] Improved handling for the PSBTOverview loading screen spinner Fixes #188 * Only runs the spinner when the psbt actually needs to be reparsed (returning to the PSBT Overview screen via BACK button doesn't need to reparse the psbt so the spinner is no longer displayed). --- src/seedsigner/views/psbt_views.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index 5e2149cc..1895a273 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -84,18 +84,22 @@ class PSBTOverviewView(View): def __init__(self): super().__init__() - # The PSBTParser takes a while to read the PSBT. Run the loading screen while we - # wait. - self.loading_screen = LoadingScreenThread(text="Parsing PSBT...") - self.loading_screen.start() + self.loading_screen = None if not self.controller.psbt_parser or self.controller.psbt_parser.seed != self.controller.psbt_seed: - # Must run the PSBTParser or re-parse - self.controller.psbt_parser = PSBTParser( - self.controller.psbt, - seed=self.controller.psbt_seed, - network=self.settings.get_value(SettingsConstants.SETTING__NETWORK) - ) + # The PSBTParser takes a while to read the PSBT. Run the loading screen while + # we wait. + self.loading_screen = LoadingScreenThread(text="Parsing PSBT...") + self.loading_screen.start() + try: + self.controller.psbt_parser = PSBTParser( + self.controller.psbt, + seed=self.controller.psbt_seed, + network=self.settings.get_value(SettingsConstants.SETTING__NETWORK) + ) + except Exception as e: + self.loading_screen.stop() + raise e def run(self): @@ -132,7 +136,8 @@ class PSBTOverviewView(View): ) # Everything is set. Stop the loading screen - self.loading_screen.stop() + if self.loading_screen: + self.loading_screen.stop() # Run the overview screen selected_menu_num = screen.display() @@ -151,6 +156,8 @@ class PSBTOverviewView(View): else: return Destination(PSBTMathView) + + class PSBTUnsupportedScriptTypeWarningView(View): def run(self): selected_menu_num = WarningScreen( From 16cd896ea8d322dc165a45ef0f269ddcf501cd36 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Thu, 26 May 2022 17:57:16 -0500 Subject: [PATCH 4/4] Additional bulletproofing for `LoadingScreenThread` spinner --- src/seedsigner/views/psbt_views.py | 11 ++--- src/seedsigner/views/seed_views.py | 70 ++++++++++++++++-------------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index 1895a273..b5150388 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -475,11 +475,12 @@ class PSBTFinalizeView(View): loading_screen = LoadingScreenThread(text="Signing PSBT...") loading_screen.start() - sig_cnt = PSBTParser.sig_count(psbt) - psbt.sign_with(psbt_parser.root) - trimmed_psbt = PSBTParser.trim(psbt) - - loading_screen.stop() + try: + sig_cnt = PSBTParser.sig_count(psbt) + psbt.sign_with(psbt_parser.root) + trimmed_psbt = PSBTParser.trim(psbt) + finally: + loading_screen.stop() if sig_cnt == PSBTParser.sig_count(trimmed_psbt): # Signing failed / didn't do anything diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 5260f017..5370ecdb 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -648,46 +648,50 @@ class SeedExportXpubDetailsView(View): self.loading_screen = LoadingScreenThread(text="Generating xpub...") self.loading_screen.start() - if self.script_type == SettingsConstants.CUSTOM_DERIVATION: - derivation_path = self.custom_derivation - else: - derivation_path = PSBTParser.calc_derivation( - network=self.settings.get_value(SettingsConstants.SETTING__NETWORK), - wallet_type=self.sig_type, - script_type=self.script_type - ) + try: + if self.script_type == SettingsConstants.CUSTOM_DERIVATION: + derivation_path = self.custom_derivation + else: + derivation_path = PSBTParser.calc_derivation( + network=self.settings.get_value(SettingsConstants.SETTING__NETWORK), + wallet_type=self.sig_type, + script_type=self.script_type + ) - if self.settings.get_value(SettingsConstants.SETTING__XPUB_DETAILS) == SettingsConstants.OPTION__ENABLED: - embit_network = NETWORKS[SettingsConstants.map_network_to_embit(self.settings.get_value(SettingsConstants.SETTING__NETWORK))] - version = embit.bip32.detect_version( - derivation_path, - default="xpub", - network=embit_network - ) + if self.settings.get_value(SettingsConstants.SETTING__XPUB_DETAILS) == SettingsConstants.OPTION__ENABLED: + embit_network = NETWORKS[SettingsConstants.map_network_to_embit(self.settings.get_value(SettingsConstants.SETTING__NETWORK))] + version = embit.bip32.detect_version( + derivation_path, + default="xpub", + network=embit_network + ) - root = embit.bip32.HDKey.from_seed( - self.seed.seed_bytes, - version=embit_network["xprv"] - ) + root = embit.bip32.HDKey.from_seed( + self.seed.seed_bytes, + version=embit_network["xprv"] + ) - fingerprint = hexlify(root.child(0).fingerprint).decode('utf-8') - xprv = root.derive(derivation_path) - xpub = xprv.to_public() - xpub_base58 = xpub.to_string(version=version) + fingerprint = hexlify(root.child(0).fingerprint).decode('utf-8') + xprv = root.derive(derivation_path) + xpub = xprv.to_public() + xpub_base58 = xpub.to_string(version=version) - screen = seed_screens.SeedExportXpubDetailsScreen( - fingerprint=fingerprint, - has_passphrase=self.seed.passphrase is not None, - derivation_path=derivation_path, - xpub=xpub_base58, - ) + screen = seed_screens.SeedExportXpubDetailsScreen( + fingerprint=fingerprint, + has_passphrase=self.seed.passphrase is not None, + derivation_path=derivation_path, + xpub=xpub_base58, + ) + self.loading_screen.stop() + selected_menu_num = screen.display() + + else: + selected_menu_num = 0 + + finally: self.loading_screen.stop() - selected_menu_num = screen.display() - else: - self.loading_screen.stop() - selected_menu_num = 0 if selected_menu_num == 0: return Destination(