import cleanup/isolation

Also removes some legacy screenshot-related workarounds that are no longer necessary.
This commit is contained in:
kdmukai
2024-11-02 12:44:56 -05:00
parent a353e26bea
commit e4c4cb4edf
11 changed files with 111 additions and 85 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: seedsigner 0.8.5\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-11-01 16:48-0500\n"
"POT-Creation-Date: 2024-11-02 12:38-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1012,7 +1012,7 @@ msgid "Scan a SeedQR"
msgstr ""
#: src/seedsigner/views/seed_views.py
msgid "Create a seed"
msgid " Create a seed"
msgstr ""
#: src/seedsigner/views/seed_views.py
+1 -16
View File
@@ -1,8 +1,6 @@
import logging
import time
import traceback
import gettext
import os
from embit.descriptor import Descriptor
from embit.psbt import PSBT
@@ -140,9 +138,6 @@ class Controller(Singleton):
screensaver: ScreensaverScreen = None
toast_notification_thread: BaseToastOverlayManagerThread = None
# Multilanguage / Localization (l10n) initialization
gettext.install('messages', localedir='seedsigner/resources/seedsigner-translations/l10n')
@classmethod
def get_instance(cls):
@@ -155,17 +150,7 @@ class Controller(Singleton):
@classmethod
def configure_instance(cls, disable_hardware=False):
"""
- `disable_hardware` is only meant to be used by the test suite so that it
can keep re-initializing a Controller in however many tests it needs to. But
this is only possible if the hardware isn't already being reserved. Without
this you get:
RuntimeError: Conflicting edge detection already enabled for this GPIO channel
each time you try to re-initialize a Controller.
"""
def configure_instance(cls):
from seedsigner.gui.renderer import Renderer
from seedsigner.hardware.microsd import MicroSD
+4 -5
View File
@@ -5,14 +5,13 @@ from dataclasses import dataclass
from gettext import gettext as _
from gettext import ngettext
from PIL import Image, ImageDraw, ImageFilter
from typing import List
from seedsigner.gui.components import (BtcAmount, Icon, FontAwesomeIconConstants, IconTextLine, FormattedAddress, GUIConstants, Fonts, SeedSignerIconConstants, TextArea,
calc_bezier_curve, linear_interp)
from seedsigner.gui.renderer import Renderer
from seedsigner.models.threads import BaseThread
from .screen import ButtonListScreen, WarningScreen
from ..components import (BtcAmount, Button, Icon, FontAwesomeIconConstants, IconTextLine, FormattedAddress, GUIConstants, Fonts, SeedSignerIconConstants, TextArea,
calc_bezier_curve, linear_interp)
from .screen import ButtonListScreen
@@ -24,7 +23,7 @@ class PSBTOverviewScreen(ButtonListScreen):
num_inputs: int = 0
num_self_transfer_outputs: int = 0
num_change_outputs: int = 0
destination_addresses: List[str] = None
destination_addresses: list[str] = None
has_op_return: bool = False
+9 -6
View File
@@ -5,13 +5,11 @@ from gettext import gettext as _
from PIL import Image, ImageDraw
from seedsigner.gui import renderer
from seedsigner.hardware.buttons import HardwareButtonsConstants
from seedsigner.hardware.camera import Camera
from seedsigner.models.decode_qr import DecodeQR, DecodeQRStatus
from seedsigner.gui.components import GUIConstants, Fonts
from seedsigner.models.decode_qr import DecodeQR
from seedsigner.models.threads import BaseThread, ThreadsafeCounter
from .screen import BaseScreen
from ..components import GUIConstants, Fonts, SeedSignerIconConstants
@@ -78,8 +76,10 @@ class ScanScreen(BaseScreen):
class LivePreviewThread(BaseThread):
def __init__(self, camera: Camera, decoder: DecodeQR, renderer: renderer.Renderer, instructions_text: str, render_rect: tuple[int,int,int,int], frame_decode_status: ThreadsafeCounter, frames_decoded_counter: ThreadsafeCounter):
self.camera = camera
def __init__(self, decoder: DecodeQR, renderer: renderer.Renderer, instructions_text: str, render_rect: tuple[int,int,int,int], frame_decode_status: ThreadsafeCounter, frames_decoded_counter: ThreadsafeCounter):
from seedsigner.hardware.camera import Camera
self.camera = Camera.get_instance()
self.decoder = decoder
self.renderer = renderer
self.instructions_text = instructions_text
@@ -252,6 +252,9 @@ class ScanScreen(BaseScreen):
Screen. Once interaction starts, the display updates have to be managed in
_run(). The live preview is an extra-complex case.
"""
from seedsigner.hardware.buttons import HardwareButtonsConstants
from seedsigner.models.decode_qr import DecodeQRStatus
num_frames = 0
start_time = time.time()
while True:
+5 -6
View File
@@ -9,7 +9,6 @@ from seedsigner.gui.components import (GUIConstants,
BaseComponent, Button, Icon, IconButton, LargeIconButton,
SeedSignerIconConstants, TopNav, TextArea, load_image)
from seedsigner.gui.keyboard import Keyboard, TextEntryDisplay
from seedsigner.gui.renderer import Renderer
from seedsigner.hardware.buttons import HardwareButtonsConstants, HardwareButtons
from seedsigner.models.encode_qr import BaseQrEncoder
from seedsigner.models.settings import SettingsConstants
@@ -125,6 +124,7 @@ class LoadingScreenThread(BaseThread):
def run(self):
from seedsigner.gui.renderer import Renderer
renderer: Renderer = Renderer.get_instance()
center_image = load_image("btc_logo_60x60.png")
@@ -181,7 +181,7 @@ class LoadingScreenThread(BaseThread):
width=GUIConstants.COMPONENT_PADDING
)
renderer.show_image(is_background_thread=True)
renderer.show_image()
position += arc_sweep
@@ -675,12 +675,12 @@ class QRDisplayScreen(BaseScreen):
qr_encoder: BaseQrEncoder = None
class QRDisplayThread(BaseThread):
def __init__(self, qr_encoder: BaseQrEncoder, qr_brightness: ThreadsafeCounter, renderer: Renderer,
tips_start_time: ThreadsafeCounter):
def __init__(self, qr_encoder: BaseQrEncoder, qr_brightness: ThreadsafeCounter, tips_start_time: ThreadsafeCounter):
from seedsigner.gui.renderer import Renderer
super().__init__()
self.qr_encoder = qr_encoder
self.qr_brightness = qr_brightness
self.renderer = renderer
self.renderer = Renderer.get_instance()
self.tips_start_time = tips_start_time
@@ -807,7 +807,6 @@ class QRDisplayScreen(BaseScreen):
self.threads.append(QRDisplayScreen.QRDisplayThread(
qr_encoder=self.qr_encoder,
qr_brightness=self.qr_brightness,
renderer=self.renderer,
tips_start_time=self.tips_start_time
))
+17 -7
View File
@@ -1,14 +1,8 @@
from gettext import gettext as _
from embit.psbt import PSBT
from embit import script
from embit.networks import NETWORKS
from seedsigner.controller import Controller
from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants
from seedsigner.models.encode_qr import UrPsbtQrEncoder
from seedsigner.models.psbt_parser import PSBTParser
from seedsigner.models.settings import SettingsConstants
from seedsigner.gui.screens.psbt_screens import PSBTOpReturnScreen, PSBTOverviewScreen, PSBTMathScreen, PSBTAddressDetailsScreen, PSBTChangeDetailsScreen, PSBTFinalizeScreen
from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants
from seedsigner.gui.screens.screen import (RET_CODE__BACK_BUTTON, ButtonListScreen, WarningScreen, DireWarningScreen, QRDisplayScreen)
from seedsigner.views.view import BackStackView, MainMenuView, NotYetImplementedView, View, Destination
@@ -22,6 +16,8 @@ class PSBTSelectSeedView(View):
def run(self):
from seedsigner.controller import Controller
# Note: we can't just autoroute to the PSBT Overview because we might have a
# multisig where we want to sign with more than one key on this device.
if not self.controller.psbt:
@@ -111,6 +107,7 @@ class PSBTOverviewView(View):
def run(self):
from seedsigner.gui.screens.psbt_screens import PSBTOverviewScreen
psbt_parser = self.controller.psbt_parser
change_data = psbt_parser.change_data
@@ -217,6 +214,7 @@ 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
@@ -253,6 +251,7 @@ class PSBTAddressDetailsView(View):
def run(self):
from seedsigner.gui.screens.psbt_screens import PSBTAddressDetailsScreen
psbt_parser: PSBTParser = self.controller.psbt_parser
if not psbt_parser:
@@ -311,6 +310,7 @@ class PSBTChangeDetailsView(View):
def run(self):
from seedsigner.gui.screens.psbt_screens import PSBTChangeDetailsScreen
psbt_parser: PSBTParser = self.controller.psbt_parser
if not psbt_parser:
@@ -367,6 +367,9 @@ class PSBTChangeDetailsView(View):
else:
# Single sig
try:
from embit import script
from embit.networks import NETWORKS
if is_change_derivation_path:
loading_screen_text = _("Verifying Change...")
else:
@@ -442,6 +445,7 @@ class PSBTChangeDetailsView(View):
return Destination(PSBTFinalizeView)
elif button_data[selected_menu_num] == self.VERIFY_MULTISIG:
from seedsigner.controller import Controller
from seedsigner.views.seed_views import LoadMultisigWalletDescriptorView
self.controller.resume_main_flow = Controller.FLOW__PSBT
return Destination(LoadMultisigWalletDescriptorView)
@@ -484,6 +488,7 @@ class PSBTOpReturnView(View):
Shows the OP_RETURN data
"""
def run(self):
from seedsigner.gui.screens.psbt_screens import PSBTOpReturnScreen
psbt_parser: PSBTParser = self.controller.psbt_parser
if not psbt_parser:
@@ -514,6 +519,9 @@ class PSBTFinalizeView(View):
def run(self):
from embit.psbt import PSBT
from seedsigner.gui.screens.psbt_screens import PSBTFinalizeScreen
psbt_parser: PSBTParser = self.controller.psbt_parser
psbt: PSBT = self.controller.psbt
self.APPROVE_PSBT = _("Approve PSBT")
@@ -550,6 +558,8 @@ class PSBTFinalizeView(View):
class PSBTSignedQRDisplayView(View):
def run(self):
from seedsigner.models.encode_qr import UrPsbtQrEncoder
qr_encoder = UrPsbtQrEncoder(
psbt=self.controller.psbt,
qr_density=self.settings.get_value(SettingsConstants.SETTING__QR_DENSITY),
+7 -7
View File
@@ -3,18 +3,13 @@ import re
from gettext import gettext as _
from embit.descriptor import Descriptor
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON
from seedsigner.models.decode_qr import DecodeQR
from seedsigner.models.seed import Seed
from seedsigner.models.settings import SettingsConstants
from seedsigner.views.settings_views import SettingsIngestSettingsQRView
from seedsigner.views.view import BackStackView, ErrorView, MainMenuView, NotYetImplementedView, OptionDisabledView, View, Destination
from seedsigner.views.view import BackStackView, ErrorView, MainMenuView, NotYetImplementedView, View, Destination
logger = logging.getLogger(__name__)
class ScanView(View):
"""
The catch-all generic scanning View that will accept any of our supported QR
@@ -29,6 +24,8 @@ class ScanView(View):
def __init__(self):
from seedsigner.models.decode_qr import DecodeQR
super().__init__()
# Define the decoder here to make it available to child classes' is_valid_qr_type
# checks and so we can inject data into it in the test suite's `before_run()`.
@@ -80,6 +77,7 @@ class ScanView(View):
else:
# Found a valid mnemonic seed! All new seeds should be considered
# pending (might set a passphrase, SeedXOR, etc) until finalized.
from seedsigner.models.seed import Seed
from .seed_views import SeedFinalizeView
self.controller.storage.set_pending_seed(
Seed(mnemonic=seed_mnemonic, wordlist_language_code=self.wordlist_language_code)
@@ -98,10 +96,12 @@ class ScanView(View):
return Destination(PSBTSelectSeedView, skip_current_view=True)
elif self.decoder.is_settings:
from seedsigner.views.settings_views import SettingsIngestSettingsQRView
data = self.decoder.get_settings_data()
return Destination(SettingsIngestSettingsQRView, view_args=dict(data=data))
elif self.decoder.is_wallet_descriptor:
from embit.descriptor import Descriptor
from seedsigner.views.seed_views import MultisigWalletDescriptorView
descriptor_str = self.decoder.get_wallet_descriptor()
+2 -1
View File
@@ -4,7 +4,6 @@ import random
import time
from gettext import gettext as _
from PIL import Image
from seedsigner.gui.components import Fonts, GUIConstants, load_image
from seedsigner.gui.screens.screen import BaseScreen
@@ -37,6 +36,7 @@ class LogoScreen(BaseScreen):
class OpeningSplashScreen(LogoScreen):
def start(self):
from PIL import Image
from seedsigner.controller import Controller
controller = Controller.get_instance()
@@ -95,6 +95,7 @@ class OpeningSplashScreen(LogoScreen):
class ScreensaverScreen(LogoScreen):
def __init__(self, buttons):
from PIL import Image
super().__init__()
self.buttons = buttons
+40 -17
View File
@@ -1,27 +1,18 @@
import logging
import embit
import random
import time
from binascii import hexlify
from embit import bip39
from embit.descriptor import Descriptor
from embit.networks import NETWORKS
from gettext import gettext as _
from typing import List
from seedsigner.controller import Controller
from embit.descriptor import Descriptor
from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants
from seedsigner.helpers import embit_utils
from seedsigner.gui.screens import (RET_CODE__BACK_BUTTON, ButtonListScreen,
WarningScreen, DireWarningScreen, seed_screens)
from seedsigner.gui.screens.screen import LargeIconStatusScreen, QRDisplayScreen
from seedsigner.helpers import embit_utils
from seedsigner.models.decode_qr import DecodeQR
from seedsigner.models.encode_qr import CompactSeedQrEncoder, GenericStaticQrEncoder, SeedQrEncoder, SpecterXPubQrEncoder, StaticXpubQrEncoder, UrXpubQrEncoder
from seedsigner.models.psbt_parser import PSBTParser
from seedsigner.models.qr_type import QRType
from seedsigner.models.seed import InvalidSeedException, Seed
from seedsigner.models.seed import Seed
from seedsigner.models.settings import Settings, SettingsConstants
from seedsigner.models.settings_definition import SettingsDefinition
from seedsigner.models.threads import BaseThread, ThreadsafeCounter
@@ -30,6 +21,7 @@ from seedsigner.views.view import NotYetImplementedView, OptionDisabledView, Vie
logger = logging.getLogger(__name__)
class SeedsMenuView(View):
LOAD = "Load a seed"
@@ -84,12 +76,16 @@ class SeedSelectSeedView(View):
TYPE_ELECTRUM = (_("Enter Electrum seed"), FontAwesomeIconConstants.KEYBOARD)
def __init__(self, flow: str = Controller.FLOW__VERIFY_SINGLESIG_ADDR):
def __init__(self, flow: str = None):
from seedsigner.controller import Controller
super().__init__()
if not flow:
flow = Controller.FLOW__VERIFY_SINGLESIG_ADDR
self.flow = flow
def run(self):
from seedsigner.controller import Controller
seeds = self.controller.storage.seeds
if self.flow == Controller.FLOW__VERIFY_SINGLESIG_ADDR:
@@ -267,6 +263,7 @@ class SeedMnemonicEntryView(View):
)
else:
# Attempt to finalize the mnemonic
from seedsigner.models.seed import InvalidSeedException
try:
self.controller.storage.convert_pending_mnemonic_to_pending_seed()
except InvalidSeedException:
@@ -282,7 +279,7 @@ class SeedMnemonicInvalidView(View):
def __init__(self):
super().__init__()
self.mnemonic: List[str] = self.controller.storage.pending_mnemonic
self.mnemonic: list[str] = self.controller.storage.pending_mnemonic
def run(self):
@@ -538,6 +535,7 @@ class SeedOptionsView(View):
def run(self):
from seedsigner.controller import Controller
from seedsigner.views.psbt_views import PSBTOverviewView
if self.controller.unverified_address:
@@ -557,6 +555,7 @@ class SeedOptionsView(View):
return Destination(SeedSignMessageConfirmMessageView, skip_current_view=True)
if self.controller.psbt:
from seedsigner.models.psbt_parser import PSBTParser
if PSBTParser.has_matching_input_fingerprint(self.controller.psbt, self.seed, network=self.settings.get_value(SettingsConstants.SETTING__NETWORK)):
if self.controller.resume_main_flow and self.controller.resume_main_flow == Controller.FLOW__PSBT:
# Re-route us directly back to the start of the PSBT flow
@@ -708,6 +707,7 @@ class SeedExportXpubScriptTypeView(View):
def run(self):
from seedsigner.controller import Controller
from .tools_views import ToolsAddressExplorerAddressTypeView
args = {"seed_num": self.seed_num, "sig_type": self.sig_type}
@@ -777,6 +777,7 @@ class SeedExportXpubCustomDerivationView(View):
def run(self):
from seedsigner.controller import Controller
ret = self.run_screen(
seed_screens.SeedExportXpubCustomDerivationScreen,
initial_value=self.custom_derivation_path,
@@ -911,6 +912,7 @@ class SeedExportXpubDetailsView(View):
elif seed_derivation_override:
derivation_path = seed_derivation_override
else:
from seedsigner.helpers import embit_utils
derivation_path = embit_utils.get_standard_derivation_path(
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK),
wallet_type=self.sig_type,
@@ -928,13 +930,15 @@ class SeedExportXpubDetailsView(View):
self.loading_screen.start()
try:
from embit.bip32 import HDKey
from embit.networks import NETWORKS
embit_network = NETWORKS[SettingsConstants.map_network_to_embit(self.settings.get_value(SettingsConstants.SETTING__NETWORK))]
version = self.seed.detect_version(
derivation_path,
self.settings.get_value(SettingsConstants.SETTING__NETWORK),
self.sig_type
)
root = embit.bip32.HDKey.from_seed(
root = HDKey.from_seed(
self.seed.seed_bytes,
version=embit_network["xprv"]
)
@@ -995,6 +999,7 @@ class SeedExportXpubQRDisplayView(View):
def run(self):
from seedsigner.gui.screens.screen import QRDisplayScreen
self.run_screen(
QRDisplayScreen,
qr_encoder=self.qr_encoder
@@ -1249,7 +1254,7 @@ class SeedWordsBackupTestPromptView(View):
class SeedWordsBackupTestView(View):
def __init__(self, seed_num: int, bip85_data: dict = None, confirmed_list: List[bool] = None, cur_index: int = None):
def __init__(self, seed_num: int, bip85_data: dict = None, confirmed_list: list[bool] = None, cur_index: int = None):
super().__init__()
self.seed_num = seed_num
if self.seed_num is None:
@@ -1271,6 +1276,8 @@ class SeedWordsBackupTestView(View):
def run(self):
from embit import bip39
if self.cur_index is None:
self.cur_index = int(random.random() * len(self.mnemonic_list))
while self.cur_index in self.confirmed_list:
@@ -1328,7 +1335,7 @@ class SeedWordsBackupTestMistakeView(View):
REVIEW = _("Review Seed Words")
RETRY = _("Try Again")
def __init__(self, seed_num: int, bip85_data: dict = None, cur_index: int = None, wrong_word: str = None, confirmed_list: List[bool] = None):
def __init__(self, seed_num: int, bip85_data: dict = None, cur_index: int = None, wrong_word: str = None, confirmed_list: list[bool] = None):
super().__init__()
self.seed_num = seed_num
self.bip85_data = bip85_data
@@ -1379,6 +1386,7 @@ class SeedWordsBackupTestSuccessView(View):
self.seed_num = seed_num
def run(self):
from seedsigner.gui.screens.screen import LargeIconStatusScreen
LargeIconStatusScreen(
title=_("Backup Verified"),
show_back_button=False,
@@ -1608,6 +1616,7 @@ class SeedTranscribeSeedQRConfirmScanView(View):
def run(self):
from seedsigner.gui.screens.scan_screens import ScanScreen
from seedsigner.models.decode_qr import DecodeQR
# Run the live preview and QR code capture process
# TODO: Does this belong in its own BaseThread?
@@ -1634,6 +1643,7 @@ class SeedTranscribeSeedQRConfirmScanView(View):
return Destination(BackStackView, skip_current_view=True)
else:
from seedsigner.gui.screens.screen import LargeIconStatusScreen
LargeIconStatusScreen(
title=_("Confirm SeedQR"),
status_headline=_("Success!"),
@@ -1672,6 +1682,7 @@ class AddressVerificationStartView(View):
def run(self):
from seedsigner.helpers import embit_utils
if self.controller.unverified_address["script_type"] == SettingsConstants.LEGACY_P2PKH:
# Legacy P2PKH addresses are always singlesig
sig_type = SettingsConstants.SINGLE_SIG
@@ -1689,6 +1700,7 @@ class AddressVerificationStartView(View):
# Can jump straight to the brute-force verification View
destination = Destination(SeedAddressVerificationView, skip_current_view=True)
else:
from seedsigner.controller import Controller
self.controller.resume_main_flow = Controller.FLOW__VERIFY_MULTISIG_ADDR
destination = Destination(LoadMultisigWalletDescriptorView, skip_current_view=True)
@@ -1718,6 +1730,8 @@ class AddressVerificationSigTypeView(View):
MULTISIG = _("Multisig")
def run(self):
from seedsigner.helpers import embit_utils
from seedsigner.controller import Controller
button_data = [self.SINGLE_SIG, self.MULTISIG]
selected_menu_num = self.run_screen(
seed_screens.AddressVerificationSigTypeScreen,
@@ -1909,6 +1923,7 @@ class SeedAddressVerificationView(View):
def run(self):
from seedsigner.helpers import embit_utils
while self.keep_running:
if self.threadsafe_counter.cur_count % 10 == 0:
logger.info(f"Incremented to {self.threadsafe_counter.cur_count}")
@@ -1949,6 +1964,7 @@ class AddressVerificationSuccessView(View):
def run(self):
from seedsigner.gui.screens.screen import LargeIconStatusScreen
address = self.controller.unverified_address["address"]
sig_type = self.controller.unverified_address["sig_type"]
verified_index = self.controller.unverified_address["verified_index"]
@@ -2000,6 +2016,7 @@ class LoadMultisigWalletDescriptorView(View):
return Destination(ScanWalletDescriptorView)
elif button_data[selected_menu_num] == self.CANCEL:
from seedsigner.controller import Controller
if self.controller.resume_main_flow == Controller.FLOW__PSBT:
return Destination(BackStackView)
else:
@@ -2026,6 +2043,7 @@ class MultisigWalletDescriptorView(View):
button_data = [self.OK]
if self.controller.resume_main_flow:
from seedsigner.controller import Controller
if self.controller.resume_main_flow == Controller.FLOW__PSBT:
button_data = [self.RETURN]
elif self.controller.resume_main_flow == Controller.FLOW__VERIFY_MULTISIG_ADDR and self.controller.unverified_address:
@@ -2074,6 +2092,7 @@ class SeedSignMessageStartView(View):
load a seed first.
"""
def __init__(self, derivation_path: str, message: str):
from seedsigner.helpers import embit_utils
super().__init__()
self.derivation_path = derivation_path
self.message = message
@@ -2119,6 +2138,7 @@ class SeedSignMessageStartView(View):
# We already know which seed we're signing with
self.set_redirect(Destination(SeedSignMessageConfirmMessageView, skip_current_view=True))
else:
from seedsigner.controller import Controller
self.set_redirect(Destination(SeedSelectSeedView, view_args=dict(flow=Controller.FLOW__SIGN_MESSAGE), skip_current_view=True))
@@ -2159,6 +2179,7 @@ class SeedSignMessageConfirmMessageView(View):
class SeedSignMessageConfirmAddressView(View):
def __init__(self):
from seedsigner.helpers import embit_utils
super().__init__()
data = self.controller.sign_message_data
seed_num = data.get("seed_num")
@@ -2220,6 +2241,7 @@ class SeedSignMessageSignedMessageQRView(View):
Displays the signed message as a QR code.
"""
def __init__(self):
from seedsigner.helpers import embit_utils
super().__init__()
data = self.controller.sign_message_data
@@ -2232,6 +2254,7 @@ class SeedSignMessageSignedMessageQRView(View):
def run(self):
from seedsigner.gui.screens.screen import QRDisplayScreen
qr_encoder = GenericStaticQrEncoder(data=self.signed_message)
self.run_screen(
+4 -7
View File
@@ -1,17 +1,13 @@
from gettext import gettext as _
import logging
from seedsigner.gui.components import SeedSignerIconConstants
from seedsigner.hardware.microsd import MicroSD
from .view import View, Destination, MainMenuView
from gettext import gettext as _
from seedsigner.gui.components import SeedSignerIconConstants
from seedsigner.gui.screens import (RET_CODE__BACK_BUTTON, ButtonListScreen, settings_screens)
from seedsigner.models.settings import Settings, SettingsConstants, SettingsDefinition
logger = logging.getLogger(__name__)
from .view import View, Destination, MainMenuView
from .view import View, Destination, BackStackView, MainMenuView
logger = logging.getLogger(__name__)
@@ -194,6 +190,7 @@ class SettingsEntryUpdateSelectionView(View):
class SettingsIngestSettingsQRView(View):
def __init__(self, data: str):
from seedsigner.hardware.microsd import MicroSD
super().__init__()
# May raise an Exception which will bubble up to the Controller to display to the
+20 -11
View File
@@ -1,22 +1,13 @@
from dataclasses import dataclass
import hashlib
import logging
import os
import time
from gettext import gettext as _
from embit.descriptor import Descriptor
from PIL import Image
from PIL.ImageOps import autocontrast
from seedsigner.controller import Controller
from seedsigner.gui.components import FontAwesomeIconConstants, GUIConstants, SeedSignerIconConstants
from seedsigner.gui.screens import (RET_CODE__BACK_BUTTON, ButtonListScreen, WarningScreen)
from seedsigner.gui.screens.tools_screens import (ToolsCalcFinalWordDoneScreen, ToolsCalcFinalWordFinalizePromptScreen,
ToolsCalcFinalWordScreen, ToolsCoinFlipEntryScreen, ToolsDiceEntropyEntryScreen, ToolsImageEntropyFinalImageScreen,
ToolsImageEntropyLivePreviewScreen, ToolsAddressExplorerAddressTypeScreen)
from seedsigner.helpers import embit_utils, mnemonic_generation
from seedsigner.models.encode_qr import GenericStaticQrEncoder
from seedsigner.gui.screens import RET_CODE__BACK_BUTTON, ButtonListScreen
from seedsigner.helpers import mnemonic_generation
from seedsigner.models.seed import Seed
from seedsigner.models.settings_definition import SettingsConstants
from seedsigner.views.seed_views import SeedDiscardView, SeedFinalizeView, SeedMnemonicEntryView, SeedOptionsView, SeedWordsWarningView, SeedExportXpubScriptTypeView
@@ -26,6 +17,7 @@ from .view import View, Destination, BackStackView
logger = logging.getLogger(__name__)
class ToolsMenuView(View):
IMAGE = (_("New seed"), FontAwesomeIconConstants.CAMERA)
DICE = (_("New seed"), FontAwesomeIconConstants.DICE)
@@ -69,6 +61,7 @@ class ToolsMenuView(View):
****************************************************************************"""
class ToolsImageEntropyLivePreviewView(View):
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsImageEntropyLivePreviewScreen
self.controller.image_entropy_preview_frames = None
ret = ToolsImageEntropyLivePreviewScreen().display()
@@ -82,6 +75,9 @@ class ToolsImageEntropyLivePreviewView(View):
class ToolsImageEntropyFinalImageView(View):
def run(self):
from PIL import Image
from PIL.ImageOps import autocontrast
from seedsigner.gui.screens.tools_screens import ToolsImageEntropyFinalImageScreen
if not self.controller.image_entropy_final_image:
from seedsigner.hardware.camera import Camera
# Take the final full-res image
@@ -224,6 +220,7 @@ class ToolsDiceEntropyEntryView(View):
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsDiceEntropyEntryScreen
ret = ToolsDiceEntropyEntryScreen(
return_after_n_chars=self.total_rolls,
).display()
@@ -288,6 +285,7 @@ class ToolsCalcFinalWordFinalizePromptView(View):
ZEROS = _("Finalize with zeros")
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordFinalizePromptScreen
mnemonic = self.controller.storage.pending_mnemonic
mnemonic_length = len(mnemonic)
if mnemonic_length == 12:
@@ -324,6 +322,7 @@ class ToolsCalcFinalWordFinalizePromptView(View):
class ToolsCalcFinalWordCoinFlipsView(View):
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsCoinFlipEntryScreen
mnemonic_length = len(self.controller.storage.pending_mnemonic)
if mnemonic_length == 12:
@@ -398,6 +397,7 @@ class ToolsCalcFinalWordShowFinalWordView(View):
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordScreen
button_data = [self.NEXT]
selected_menu_num = self.run_screen(
ToolsCalcFinalWordScreen,
@@ -423,6 +423,7 @@ class ToolsCalcFinalWordDoneView(View):
DISCARD = (_("Discard"), None, None, "red")
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordDoneScreen
mnemonic = self.controller.storage.pending_mnemonic
mnemonic_word_length = len(mnemonic)
final_word = mnemonic[-1]
@@ -460,6 +461,8 @@ class ToolsAddressExplorerSelectSourceView(View):
TYPE_ELECTRUM = (_("Enter Electrum seed"), FontAwesomeIconConstants.KEYBOARD)
def run(self):
from seedsigner.controller import Controller
seeds = self.controller.storage.seeds
button_data = []
for seed in seeds:
@@ -558,6 +561,7 @@ class ToolsAddressExplorerAddressTypeView(View):
elif seed_derivation_override:
derivation_path = seed_derivation_override
else:
from seedsigner.helpers import embit_utils
derivation_path = embit_utils.get_standard_derivation_path(
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK),
wallet_type=SettingsConstants.SINGLE_SIG,
@@ -574,6 +578,7 @@ class ToolsAddressExplorerAddressTypeView(View):
def run(self):
from seedsigner.gui.screens.tools_screens import ToolsAddressExplorerAddressTypeScreen
data = self.controller.address_explorer_data
wallet_descriptor_display_name = None
@@ -638,6 +643,7 @@ class ToolsAddressExplorerAddressListView(View):
else:
try:
from seedsigner.gui.screens.screen import LoadingScreenThread
from seedsigner.helpers import embit_utils
# TRANSLATOR_NOTE: a status message that our payment addresses are being calculated
self.loading_screen = LoadingScreenThread(text=_("Calculating addrs..."))
self.loading_screen.start()
@@ -658,6 +664,7 @@ class ToolsAddressExplorerAddressListView(View):
raise Exception(_("Custom Derivation address explorer not yet implemented"))
elif "wallet_descriptor" in data:
from embit.descriptor import Descriptor
descriptor: Descriptor = data["wallet_descriptor"]
if descriptor.is_basic_multisig:
for i in range(self.start_index, self.start_index + addrs_per_screen):
@@ -726,6 +733,8 @@ class ToolsAddressExplorerAddressView(View):
def run(self):
from seedsigner.gui.screens.screen import QRDisplayScreen
from seedsigner.models.encode_qr import GenericStaticQrEncoder
qr_encoder = GenericStaticQrEncoder(data=self.address)
self.run_screen(
QRDisplayScreen,