mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
import cleanup/isolation
Also removes some legacy screenshot-related workarounds that are no longer necessary.
This commit is contained in:
+2
-2
@@ -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,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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
))
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user