diff --git a/docs/manual_installation.md b/docs/manual_installation.md index 585d3eef..236d77c4 100644 --- a/docs/manual_installation.md +++ b/docs/manual_installation.md @@ -190,7 +190,7 @@ Description=Seedsigner [Service] User=pi WorkingDirectory=/home/pi/seedsigner/src/ -ExecStart=/home/pi/.envs/seedsigner-env/bin/python -u main.py +ExecStart=/home/pi/.envs/seedsigner-env/bin/python3 main.py > /dev/null 2>&1 Restart=always [Install] @@ -199,6 +199,8 @@ WantedBy=multi-user.target _Note: For local dev you'll want to edit the `Restart=always` line to `Restart=no`. This way when your dev code crashes it won't keep trying to restart itself. Note that the UI "Reset" will no longer work when auto-restarts are disabled._ +_Note: Debugging output is completely wiped via routing the output to `/dev/null 2>&1`. When working in local dev, you're better off disabling the `systemd` SeedSigner service and just directly running the app so you can see all the debugging output live._ + Use `CTRL-X` and `y` to exit and save changes. Configure the service to start running (this will restart the seedsigner code automatically at startup and if it crashes): diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index c899381e..abf32014 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -36,7 +36,7 @@ class PSBTOverviewScreen(ButtonListScreen): # Prep the headline amount being spent in large callout # icon_text_lines_y = self.components[-1].screen_y + self.components[-1].height - icon_text_lines_y = self.top_nav.height + icon_text_lines_y = self.top_nav.height + GUIConstants.COMPONENT_PADDING if not self.destination_addresses: @@ -447,22 +447,6 @@ class PSBTOverviewScreen(ButtonListScreen): -@dataclass -class PSBTNoChangeWarningScreen(WarningScreen): - fingerprint: str = None - - def __post_init__(self): - # Customize defaults - self.title: str = "Caution" - self.button_data: list = ["Continue"] - self.is_bottom_list: bool = True - self.warning_headline: str = "Full Spend!" # The colored text under the alert icon - self.warning_text: str = "This PSBT spends its entire input value. No change is coming back to your wallet." # The body text of the warning - - super().__post_init__() - - - @dataclass class PSBTMathScreen(ButtonListScreen): input_amount: int = 0 @@ -623,7 +607,7 @@ class PSBTAddressDetailsScreen(ButtonListScreen): is_text_centered=True, value_text=f"{amount_display}", font_size=22, - screen_y=0, + screen_y=int(GUIConstants.COMPONENT_PADDING/2), ) formatted_address = FormattedAddress( diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index cefd007d..01b7bb4b 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -1,4 +1,3 @@ -import time from embit.psbt import PSBT from seedsigner.models.encode_qr import EncodeQR @@ -37,7 +36,7 @@ class PSBTSelectSeedView(View): if seed.passphrase is not None: # TODO: Include lock icon on right side of button pass - button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT)) + button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue")) button_data.append(SCAN_SEED) button_data.append(ENTER_WORDS) @@ -135,7 +134,11 @@ class PSBTOverviewView(View): class PSBTNoChangeWarningView(View): def run(self): - selected_menu_num = psbt_screens.PSBTNoChangeWarningScreen().display() + selected_menu_num = WarningScreen( + status_headline="Full Spend!", + text="This PSBT spends its entire input value. No change is coming back to your wallet.", + button_data=["Continue"], + ).display() if selected_menu_num == RET_CODE__BACK_BUTTON: return Destination(BackStackView) @@ -155,14 +158,12 @@ class PSBTMathView(View): + change value """ def run(self): - from seedsigner.gui.screens.psbt_screens import PSBTMathScreen - psbt_parser: PSBTParser = self.controller.psbt_parser if not psbt_parser: # Should not be able to get here return Destination(MainMenuView) - selected_menu_num = PSBTMathScreen( + selected_menu_num = psbt_screens.PSBTMathScreen( input_amount=psbt_parser.input_amount, num_inputs=psbt_parser.num_inputs, spend_amount=psbt_parser.spend_amount, @@ -294,7 +295,7 @@ class PSBTChangeDetailsView(View): # if the known-good multisig descriptor is already onboard: # calc change addr... # is_change_addr_verified = True - # button_data = [VERIFY_MULTISIG, NEXT] + # button_data = [NEXT] # else: # Have the Screen offer to load in the multisig descriptor. @@ -413,7 +414,7 @@ class PSBTSignedQRDisplayView(View): qr_density=self.settings.get_value(SettingsConstants.SETTING__QR_DENSITY), wordlist_language_code=self.settings.get_value(SettingsConstants.SETTING__WORDLIST_LANGUAGE), ) - ret = QRDisplayScreen(qr_encoder=qr_encoder).display() + QRDisplayScreen(qr_encoder=qr_encoder).display() # We're done with this PSBT. Remove all related data self.controller.psbt = None @@ -431,6 +432,7 @@ class PSBTSigningErrorView(View): # Should not be able to get here return Destination(MainMenuView) + # Just a WarningScreen here; only use DireWarningScreen for true security risks. selected_menu_num = WarningScreen( title="PSBT Error", status_icon_name=SeedSignerCustomIconConstants.CIRCLE_EXCLAMATION, diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 8a87276f..4d137fc8 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -282,7 +282,7 @@ class SeedReviewPassphraseView(View): elif button_data[selected_menu_num] == DONE: seed_num = self.controller.storage.finalize_pending_seed() - return Destination(SeedOptionsView, view_args={"seed_num": seed_num}) + return Destination(SeedOptionsView, view_args={"seed_num": seed_num}, clear_history=True) @@ -719,7 +719,10 @@ class SeedWordsView(View): def __init__(self, seed_num: int, page_index: int = 0): super().__init__() self.seed_num = seed_num - self.seed = self.controller.get_seed(self.seed_num) + if self.seed_num is None: + self.seed = self.controller.storage.get_pending_seed() + else: + self.seed = self.controller.get_seed(self.seed_num) self.page_index = page_index self.num_pages=int(len(self.seed.mnemonic_list)/4) @@ -729,7 +732,7 @@ class SeedWordsView(View): DONE = "Done" button_data = [] - if self.page_index < self.num_pages - 1: + if self.page_index < self.num_pages - 1 or self.seed_num is None: button_data.append(NEXT) else: button_data.append(DONE) @@ -745,7 +748,10 @@ class SeedWordsView(View): return Destination(BackStackView) if button_data[selected_menu_num] == NEXT: - return Destination(SeedWordsView, view_args={"seed_num": self.seed_num, "page_index": self.page_index + 1}) + if self.seed_num is None and self.page_index == self.num_pages - 1: + return Destination(SeedFinalizeView) + else: + return Destination(SeedWordsView, view_args={"seed_num": self.seed_num, "page_index": self.page_index + 1}) elif button_data[selected_menu_num] == DONE: # Must clear history to avoid BACK button returning to private info diff --git a/src/seedsigner/views/tools_views.py b/src/seedsigner/views/tools_views.py index 25bc4e40..697f4c79 100644 --- a/src/seedsigner/views/tools_views.py +++ b/src/seedsigner/views/tools_views.py @@ -160,10 +160,9 @@ class ToolsImageEntropyMnemonicLengthView(View): # Add the mnemonic as an in-memory Seed seed = Seed(mnemonic, wordlist_language_code=self.settings.get_value(SettingsConstants.SETTING__WORDLIST_LANGUAGE)) self.controller.storage.set_pending_seed(seed) - seed_num = self.controller.storage.finalize_pending_seed() # Cannot return BACK to this View - return Destination(SeedWordsWarningView, view_args={"seed_num": seed_num}, clear_history=True) + return Destination(SeedWordsWarningView, view_args={"seed_num": None}, clear_history=True) diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index f4117221..7556be6f 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -176,9 +176,9 @@ class ResetView(View): time.sleep(0.25) # Kill the SeedSigner process; systemd will automatically restart it. - # `.*` is a wildcard to detect `python3 -u main.py` with or without the - # `-u` flag. - call("kill $(ps aux | grep '[p]ython3 .*main.py' | awk '{print $2}')", shell=True) + # `.*` is a wildcard to detect either `python`` or `python3` and with or + # without the `-u` flag. + call("kill $(ps aux | grep '[p]ython.*main.py' | awk '{print $2}')", shell=True)