From 88e215179cba513dcbf1fc0800dc2550d3bebfa4 Mon Sep 17 00:00:00 2001 From: newtonick Date: Sat, 7 Aug 2021 22:40:48 -0400 Subject: [PATCH] few tweaks and workflow improvements based on testing feedback. Also added reset/reset. --- src/default_settings.ini | 2 +- src/seedsigner/controller.py | 73 ++++++++++++++++++--- src/seedsigner/helpers/path.py | 1 + src/seedsigner/models/settings.py | 8 ++- src/seedsigner/views/menu_view.py | 6 +- src/seedsigner/views/seed_tools_view.py | 2 +- src/seedsigner/views/settings_tools_view.py | 10 +-- src/settings.ini | 2 +- 8 files changed, 82 insertions(+), 22 deletions(-) diff --git a/src/default_settings.ini b/src/default_settings.ini index e494f643..48d3e892 100644 --- a/src/default_settings.ini +++ b/src/default_settings.ini @@ -8,7 +8,7 @@ text_color = ORANGE [wallet] network = main -software = Specter Desktop +software = Prompt qr_density = 2 script_policy = PKWSH custom_derivation_enabled = False diff --git a/src/seedsigner/controller.py b/src/seedsigner/controller.py index 1adba944..cd9d766d 100644 --- a/src/seedsigner/controller.py +++ b/src/seedsigner/controller.py @@ -2,6 +2,7 @@ import time from multiprocessing import Process, Queue from subprocess import call +import os, sys from embit import bip39, bip32 from embit.networks import NETWORKS from binascii import hexlify @@ -31,7 +32,7 @@ class Controller(Singleton): Note: In many/most cases you'll need to do the Controller import within a method rather than at the top in order avoid circular imports. """ - VERSION = "0.4.3" + VERSION = "0.4.4" @classmethod @@ -147,6 +148,8 @@ class Controller(Singleton): ret_val = self.show_persistent_settings_tool() elif ret_val == Path.DONATE: ret_val = self.show_donate_tool() + elif ret_val == Path.RESET: + ret_val = self.show_reset_tool() elif ret_val == Path.POWER_OFF: ret_val = self.show_power_off() @@ -322,6 +325,17 @@ class Controller(Singleton): else: show_qr_option = True + self.menu_view.draw_modal(["Validating ..."]) + is_valid = self.storage.check_if_seed_valid(seed_phrase) + if is_valid == False: + # Exit if not valid with message + self.menu_view.draw_modal(["Seed Invalid", "check seed phrase", "and try again", ""], "", "Right to Continue") + input = self.buttons.wait_for([B.KEY_RIGHT]) + return Path.SEED_TOOLS_SUB_MENU + else: + self.menu_view.draw_modal(["Valid Seed!"], "", "Right to Continue") + input = self.buttons.wait_for([B.KEY_RIGHT]) + while display_saved_seed == False: r = self.seed_tools_view.display_seed_phrase(seed_phrase, show_qr_option=show_qr_option ) if r == True: @@ -330,14 +344,9 @@ class Controller(Singleton): # no-op; can't back out of the seed phrase view pass - self.menu_view.draw_modal(["Validating ..."]) - is_valid = self.storage.check_if_seed_valid(seed_phrase) if is_valid: self.storage.save_seed_phrase(seed_phrase, slot_num) - self.menu_view.draw_modal(["Seed Valid", "Saved to Slot #" + str(slot_num)], "", "Right to Main Menu") - input = self.buttons.wait_for([B.KEY_RIGHT]) - else: - self.menu_view.draw_modal(["Seed Invalid", "check seed phrase", "and try again"], "", "Right to Continue") + self.menu_view.draw_modal(["", "Saved to Slot #" + str(slot_num)], "", "Right to Exit") input = self.buttons.wait_for([B.KEY_RIGHT]) return Path.SEED_TOOLS_SUB_MENU @@ -488,8 +497,15 @@ class Controller(Singleton): self.signing_tools_view.display_xpub_info(fingerprint, self.settings.derivation, xpub) self.buttons.wait_for([B.KEY_RIGHT]) + if self.settings.software == "Prompt": + lines = ["Specter Desktop", "Blue Wallet", "Sparrow"] + r = self.menu_view.display_generic_selection_menu(lines, "Which Wallet?") + qr_xpub_type = Settings.getXPubType(lines[r-1]) + else: + qr_xpub_type = self.settings.qr_xpub_type + self.signing_tools_view.draw_modal(["Generating xPub QR ..."]) - e = EncodeQR(seed_phrase=seed_phrase, passphrase=passphrase, derivation=self.settings.derivation, network=self.settings.network, policy=self.settings.script_policy, qr_type=self.settings.qr_xpub_type, qr_density=self.settings.qr_density) + e = EncodeQR(seed_phrase=seed_phrase, passphrase=passphrase, derivation=self.settings.derivation, network=self.settings.network, policy=self.settings.script_policy, qr_type=qr_xpub_type, qr_density=self.settings.qr_density) while e.totalParts() > 1: image = e.nextPartImage(240,240,2) @@ -575,6 +591,16 @@ class Controller(Singleton): self.menu_view.draw_modal(["Valid Seed!"], "", "Right to Continue") input = self.buttons.wait_for([B.KEY_RIGHT]) + # Ask to save seed + if self.storage.slot_avaliable(): + r = self.menu_view.display_generic_selection_menu(["Yes", "No"], "Save Seed?") + if r == 1: #Yes + slot_num = self.menu_view.display_saved_seed_menu(self.storage,2,None) + if slot_num in (1,2,3): + self.storage.save_seed_phrase(seed_phrase, slot_num) + self.menu_view.draw_modal(["Seed Valid", "Saved to Slot #" + str(slot_num)], "", "Right to Main Menu") + input = self.buttons.wait_for([B.KEY_RIGHT]) + r = self.menu_view.display_generic_selection_menu(["Yes", "No"], "Add Seed Passphrase?") if r == 1: # display a tool to pick letters/numbers to make a passphrase @@ -605,10 +631,12 @@ class Controller(Singleton): # second QR must be a PSBT self.menu_view.draw_modal(["Validating PSBT"]) psbt = decoder.getPSBT() - else: - self.menu_view.draw_modal(["Invalid PSBT QR"], "", "Right to Exit") + elif ( decoder.isComplete() and not decoder.isPSBT() ) or decoder.isInvalid(): + self.menu_view.draw_modal(["Not a valid PSBT QR"], "", "Right to Exit") input = self.buttons.wait_for([B.KEY_RIGHT]) return Path.MAIN_MENU + else: + return Path.MAIN_MENU elif ( decoder.isComplete() and not decoder.isPSBT() ) or decoder.isInvalid(): self.menu_view.draw_modal(["Not a valid PSBT QR"], "", "Right to Exit") @@ -803,3 +831,28 @@ class Controller(Singleton): input = self.buttons.wait_for([B.KEY_RIGHT]) return Path.MAIN_MENU + def show_reset_tool(self): + self.menu_view.draw_modal(["This will restore", "default settings and", "restart the device", ""], "Warning", "Right to Continue") + input = self.buttons.wait_for([B.KEY_LEFT, B.KEY_RIGHT]) + if input == B.KEY_RIGHT: + r = self.menu_view.display_generic_selection_menu(["Yes", "No"], "Reset SeedSigner?") + if r == 1: #Yes + self.menu_view.display_blank_screen() + self.settings.restoreDefault() + time.sleep(0.1) # give time to write to disk + + return_code = os.system("sudo systemctl is-active --quiet seedsigner.service") + + if return_code == 0: + # systemd service is running + call("sudo systemctl restart seedsigner.service", shell=True) + time.sleep(2) + else: + # systemd service is not running, restart script internally + os.execv(sys.executable, ['python3'] + sys.argv) + + else: # No + return Path.MAIN_MENU + + return Path.MAIN_MENU + diff --git a/src/seedsigner/helpers/path.py b/src/seedsigner/helpers/path.py index f6247423..8658f3d3 100644 --- a/src/seedsigner/helpers/path.py +++ b/src/seedsigner/helpers/path.py @@ -29,6 +29,7 @@ class Path: QR_DENSITY_SETTING = 65 WALLET_POLICY = 66 PERSISTENT_SETTINGS = 67 + RESET = 68 # Seed Slots SEED_SLOT_1 = 80 diff --git a/src/seedsigner/models/settings.py b/src/seedsigner/models/settings.py index 8a39c2cc..b15f54b4 100644 --- a/src/seedsigner/models/settings.py +++ b/src/seedsigner/models/settings.py @@ -143,7 +143,7 @@ class Settings(Singleton): @software.setter def software(self, value): - if value in ("Specter Desktop", "Blue Wallet", "Sparrow", "UR 2.0 Generic"): + if value in ("Specter Desktop", "Blue Wallet", "Sparrow", "Prompt"): self._data["wallet"]["software"] = value self.__writeConfig() else: @@ -170,7 +170,11 @@ class Settings(Singleton): @property def qr_xpub_type(self): - if self.software in ("Specter Desktop"): + return Settings.getXPubType(self.software) + + @staticmethod + def getXPubType(software): + if software == "Specter Desktop": return QRType.SPECTERXPUBQR else: return QRType.XPUBQR diff --git a/src/seedsigner/views/menu_view.py b/src/seedsigner/views/menu_view.py index 92796be2..8e072bc7 100644 --- a/src/seedsigner/views/menu_view.py +++ b/src/seedsigner/views/menu_view.py @@ -71,7 +71,7 @@ class MenuView(View): else: seed_storage_line = "View Seeds (temp)" - lines = ["... [ Return to Main ]", "Input a Seed", "Add/Remove Passphrase", "Generate an xPub", "Generate Word 12/24", "Generate a Seed with Dice", "Generate a Seed with Image"] + lines = ["... [ Return to Main ]", "Seed Storage", "Seed Passphrase", "xPub from Seed", "Calculate Last Word", "Generate Seed with Dice", "Generate Seed with Image"] self.draw_menu(lines, 1) input = 0 @@ -124,7 +124,7 @@ class MenuView(View): ### Settings Menu def display_settings_menu(self) -> int: - lines = ["... [ Return to Main ]", "Wallet: ", "Script Policy: ", "Network: ", "QR Density: ", "Input / Output Tests", "Persistent Settings: ", "Version Info", "Donate to SeedSigner"] + lines = ["... [ Return to Main ]", "Wallet: ", "Script Policy: ", "Network: ", "QR Density: ", "Input / Output Tests", "Persistent Settings: ", "Version Info", "Donate to SeedSigner", "Reset SeedSigner"] input = 0 lines[1] = lines[1].replace("", Settings.get_instance().software) @@ -163,6 +163,8 @@ class MenuView(View): return Path.VERSION_INFO elif self.selected_menu_num == 9: return Path.DONATE + elif self.selected_menu_num == 10: + return Path.RESET raise Exception("Unhandled case") ### Generic Single Menu Selection (returns 1,2,3,4,5,6 ...) diff --git a/src/seedsigner/views/seed_tools_view.py b/src/seedsigner/views/seed_tools_view.py index 3099398c..ebd04c0d 100644 --- a/src/seedsigner/views/seed_tools_view.py +++ b/src/seedsigner/views/seed_tools_view.py @@ -1146,7 +1146,7 @@ class SeedToolsView(View): cur_y = next_y def read_seed_phrase_qr(self): - self.draw_modal(["Scanning..."], "Seed QR" ,"Left to Cancel") + self.draw_modal(["Scanning..."], "Seed QR" ,"Right to Exit") try: self.controller.camera.start_video_stream_mode(resolution=(480, 480), framerate=12, format="rgb") decoder = DecodeQR() diff --git a/src/seedsigner/views/settings_tools_view.py b/src/seedsigner/views/settings_tools_view.py index 12437219..8c16b47b 100644 --- a/src/seedsigner/views/settings_tools_view.py +++ b/src/seedsigner/views/settings_tools_view.py @@ -39,15 +39,15 @@ class SettingsToolsView(View): ### Display Wallet Selection def display_wallet_selection(self) -> str: - r = self.controller.menu_view.display_generic_selection_menu(["... [ Return to Settings ]", "Specter Desktop", "Blue Wallet", "Sparrow", "UR 2.0 Generic"], "Which Wallet?") + r = self.controller.menu_view.display_generic_selection_menu(["... [ Return to Settings ]", "Prompt", "Specter Desktop", "Blue Wallet", "Sparrow"], "Which Wallet?") if r == 2: - return "Specter Desktop" + return "Prompt" elif r == 3: - return "Blue Wallet" + return "Specter Desktop" elif r == 4: - return "Sparrow" + return "Blue Wallet" elif r == 5: - return "UR 2.0 Generic" + return "Sparrow" else: return None diff --git a/src/settings.ini b/src/settings.ini index e494f643..48d3e892 100644 --- a/src/settings.ini +++ b/src/settings.ini @@ -8,7 +8,7 @@ text_color = ORANGE [wallet] network = main -software = Specter Desktop +software = Prompt qr_density = 2 script_policy = PKWSH custom_derivation_enabled = False