mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Large refactor to add ButtonOption and mark_for_translation
This commit is contained in:
+6
-23
@@ -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-02 12:38-0500\n"
|
||||
"POT-Creation-Date: 2024-11-02 16:48-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"
|
||||
@@ -151,9 +151,6 @@ msgstr[1] ""
|
||||
msgid "{} change"
|
||||
msgstr ""
|
||||
|
||||
#. First variable is either "Multisig" or the fingerprint for single sig;
|
||||
#. Second is "Change" or "Addr" (change vs receive addr); Third is the address
|
||||
#. index number (e.g. your #4 receive addr).
|
||||
#: src/seedsigner/gui/screens/psbt_screens.py
|
||||
#: src/seedsigner/models/settings_definition.py
|
||||
#: src/seedsigner/views/seed_views.py
|
||||
@@ -164,6 +161,7 @@ msgstr ""
|
||||
msgid "Change"
|
||||
msgstr ""
|
||||
|
||||
#. Abbreviation for receive address
|
||||
#: src/seedsigner/gui/screens/psbt_screens.py
|
||||
msgid "Addr"
|
||||
msgstr ""
|
||||
@@ -263,6 +261,7 @@ msgstr ""
|
||||
#. a label for the shortened Key-id of a BIP-32 master HD wallet
|
||||
#: src/seedsigner/gui/screens/seed_screens.py
|
||||
#: src/seedsigner/gui/screens/tools_screens.py
|
||||
#: src/seedsigner/views/seed_views.py
|
||||
msgid "fingerprint"
|
||||
msgstr ""
|
||||
|
||||
@@ -817,7 +816,7 @@ msgid ""
|
||||
"addresses."
|
||||
msgstr ""
|
||||
|
||||
#: src/seedsigner/views/psbt_views.py src/seedsigner/views/view.py
|
||||
#: src/seedsigner/views/psbt_views.py
|
||||
msgid "Continue"
|
||||
msgstr ""
|
||||
|
||||
@@ -1295,11 +1294,6 @@ msgstr ""
|
||||
msgid "Return to PSBT"
|
||||
msgstr ""
|
||||
|
||||
#. Inserts mainnet/testnet/regtest and derivation path
|
||||
#: src/seedsigner/views/seed_views.py
|
||||
msgid "Current network setting ({}) doesn't match {}"
|
||||
msgstr ""
|
||||
|
||||
#: src/seedsigner/views/seed_views.py
|
||||
msgid "Signing messages for custom derivation paths not supported"
|
||||
msgstr ""
|
||||
@@ -1470,9 +1464,9 @@ msgstr ""
|
||||
msgid "Change Setting"
|
||||
msgstr ""
|
||||
|
||||
#. Inserts mainnet/testnet/regtest
|
||||
#. Inserts mainnet/testnet/regtest and derivation path
|
||||
#: src/seedsigner/views/view.py
|
||||
msgid "Current network setting ({}) doesn't match current action."
|
||||
msgid "Current network setting ({}) doesn't match {}."
|
||||
msgstr ""
|
||||
|
||||
#: src/seedsigner/views/view.py
|
||||
@@ -1493,14 +1487,3 @@ msgstr ""
|
||||
msgid "Option Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/seedsigner/views/view.py
|
||||
msgid "Security Tip"
|
||||
msgstr ""
|
||||
|
||||
#: src/seedsigner/views/view.py
|
||||
msgid ""
|
||||
"For maximum security,\n"
|
||||
"remove the MicroSD card\n"
|
||||
"before continuing."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
[extract_messages]
|
||||
keywords = _ _mft mark_for_translation ButtonOption
|
||||
add_comments = TRANSLATOR_NOTE:
|
||||
strip_comments = yes
|
||||
add_location = file
|
||||
|
||||
@@ -11,7 +11,7 @@ from seedsigner.gui.components import (BtcAmount, Icon, FontAwesomeIconConstants
|
||||
from seedsigner.gui.renderer import Renderer
|
||||
from seedsigner.models.threads import BaseThread
|
||||
|
||||
from .screen import ButtonListScreen
|
||||
from .screen import ButtonListScreen, ButtonOption
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class PSBTOverviewScreen(ButtonListScreen):
|
||||
# Customize defaults
|
||||
self.title = _("Review PSBT")
|
||||
self.is_bottom_list = True
|
||||
self.button_data = [_("Review Details")]
|
||||
self.button_data = [ButtonOption("Review Details")]
|
||||
|
||||
# This screen can take a while to load while parsing the PSBT
|
||||
self.show_loading_screen = True
|
||||
@@ -479,7 +479,7 @@ class PSBTMathScreen(ButtonListScreen):
|
||||
def __post_init__(self):
|
||||
# Customize defaults
|
||||
self.title = _("PSBT Math")
|
||||
self.button_data = [_("Review Recipients")]
|
||||
self.button_data = [ButtonOption("Review Recipients")]
|
||||
self.is_bottom_list = True
|
||||
|
||||
super().__post_init__()
|
||||
@@ -675,9 +675,18 @@ class PSBTChangeDetailsScreen(ButtonListScreen):
|
||||
))
|
||||
|
||||
screen_y = self.components[-1].screen_y + self.components[-1].height + 2*GUIConstants.COMPONENT_PADDING
|
||||
|
||||
change_type = _("Multisig") if self.is_multisig else self.fingerprint
|
||||
|
||||
if self.is_change_derivation_path :
|
||||
addr_type = _("Change")
|
||||
else:
|
||||
# TRANSLATOR_NOTE: Abbreviation for receive address
|
||||
addr_type = _("Addr")
|
||||
|
||||
value_text = "{}: {} #{}".format(change_type, addr_type, self.derivation_path_addr_index)
|
||||
self.components.append(IconTextLine(
|
||||
# TRANSLATOR_NOTE: First variable is either "Multisig" or the fingerprint for single sig; Second is "Change" or "Addr" (change vs receive addr); Third is the address index number (e.g. your #4 receive addr).
|
||||
value_text="""{}: {} #{}""".format(_("Multisig") if self.is_multisig else self.fingerprint, _("Change") if self.is_change_derivation_path else _("Addr"), self.derivation_path_addr_index),
|
||||
value_text=value_text,
|
||||
icon_name=SeedSignerIconConstants.FINGERPRINT,
|
||||
icon_color=GUIConstants.INFO_COLOR,
|
||||
is_text_centered=False,
|
||||
|
||||
@@ -5,6 +5,7 @@ from gettext import gettext as _
|
||||
from PIL import Image, ImageDraw, ImageColor
|
||||
from typing import Any, List, Tuple
|
||||
|
||||
from seedsigner.helpers.l10n import mark_for_translation as _mft
|
||||
from seedsigner.gui.components import (GUIConstants,
|
||||
BaseComponent, Button, Icon, IconButton, LargeIconButton,
|
||||
SeedSignerIconConstants, TopNav, TextArea, load_image)
|
||||
@@ -252,9 +253,23 @@ class BaseTopNavScreen(BaseScreen):
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class ButtonOption:
|
||||
"""
|
||||
Note: The babel config in setup.cfg will extract the `button_label` string for translation
|
||||
"""
|
||||
button_label: str
|
||||
icon_name: str = None
|
||||
icon_color: str = None
|
||||
right_icon_name: str = None
|
||||
button_label_color: str = None
|
||||
return_data: Any = None
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class ButtonListScreen(BaseTopNavScreen):
|
||||
button_data: list = None # list can be a mix of str or tuple(label: str, icon_name: str)
|
||||
button_data: list[ButtonOption] = None
|
||||
selected_button: int = 0
|
||||
is_button_text_centered: bool = True
|
||||
is_bottom_list: bool = False
|
||||
@@ -295,26 +310,38 @@ class ButtonListScreen(BaseTopNavScreen):
|
||||
self.has_scroll_arrows = True
|
||||
|
||||
self.buttons: List[Button] = []
|
||||
for i, button_label in enumerate(self.button_data):
|
||||
for i, button_option in enumerate(self.button_data):
|
||||
icon_name = None
|
||||
icon_color = None
|
||||
right_icon_name = None
|
||||
button_label_color = None
|
||||
|
||||
# TODO: Define an actual class for button_data?
|
||||
if type(button_label) == tuple:
|
||||
if len(button_label) == 2:
|
||||
(button_label, icon_name) = button_label
|
||||
icon_color = GUIConstants.BUTTON_FONT_COLOR
|
||||
if type(button_option) == ButtonOption:
|
||||
button_label = button_option.button_label
|
||||
icon_name = button_option.icon_name
|
||||
icon_color = button_option.icon_color
|
||||
right_icon_name = button_option.right_icon_name
|
||||
button_label_color = button_option.button_label_color
|
||||
|
||||
else:
|
||||
raise Exception("Refactor needed!")
|
||||
|
||||
elif len(button_label) == 3:
|
||||
(button_label, icon_name, icon_color) = button_label
|
||||
# # TODO: Complete refactor away from str|tuple to ButtonOption
|
||||
# elif type(button_option) == str:
|
||||
# button_label = button_option
|
||||
# elif type(button_option) == tuple:
|
||||
# if len(button_option) == 2:
|
||||
# (button_label, icon_name) = button_option
|
||||
# icon_color = GUIConstants.BUTTON_FONT_COLOR
|
||||
|
||||
elif len(button_label) == 4:
|
||||
(button_label, icon_name, icon_color, button_label_color) = button_label
|
||||
# elif len(button_option) == 3:
|
||||
# (button_label, icon_name, icon_color) = button_option
|
||||
|
||||
elif len(button_label) == 5:
|
||||
(button_label, icon_name, icon_color, button_label_color, right_icon_name) = button_label
|
||||
# elif len(button_option) == 4:
|
||||
# (button_label, icon_name, icon_color, button_label_color) = button_option
|
||||
|
||||
# elif len(button_option) == 5:
|
||||
# (button_label, icon_name, icon_color, button_label_color, right_icon_name) = button_option
|
||||
|
||||
button_kwargs = dict(
|
||||
text=_(button_label), # Wrap here for just-in-time translations
|
||||
@@ -547,11 +574,20 @@ class LargeButtonScreen(BaseTopNavScreen):
|
||||
button_start_y = self.top_nav.height + int((self.canvas_height - (self.top_nav.height + GUIConstants.COMPONENT_PADDING) - (2 * button_height) - GUIConstants.COMPONENT_PADDING) / 2)
|
||||
|
||||
self.buttons = []
|
||||
for i, button_label in enumerate(self.button_data):
|
||||
if type(button_label) == tuple:
|
||||
(button_label, icon_name) = button_label
|
||||
for i, button_option in enumerate(self.button_data):
|
||||
if type(button_option) == ButtonOption:
|
||||
button_label = button_option.button_label
|
||||
icon_name = button_option.icon_name
|
||||
else:
|
||||
icon_name = None
|
||||
raise Exception("Refactor needed!")
|
||||
|
||||
# elif type(button_option) == str:
|
||||
# button_label = button_option
|
||||
# icon_name = None
|
||||
# elif type(button_option) == tuple:
|
||||
# (button_label, icon_name) = button_option
|
||||
# else:
|
||||
# print(type(button_option))
|
||||
|
||||
if i % 2 == 0:
|
||||
button_start_x = GUIConstants.EDGE_PADDING
|
||||
@@ -848,18 +884,20 @@ class QRDisplayScreen(BaseScreen):
|
||||
|
||||
@dataclass
|
||||
class LargeIconStatusScreen(ButtonListScreen):
|
||||
title: str = _("Success!")
|
||||
title: str = _mft("Success!")
|
||||
status_icon_name: str = SeedSignerIconConstants.SUCCESS
|
||||
status_icon_size: int = GUIConstants.ICON_PRIMARY_SCREEN_SIZE
|
||||
status_color: str = GUIConstants.SUCCESS_COLOR
|
||||
status_headline: str = None
|
||||
text: str = "" # The body text of the screen
|
||||
text_edge_padding: int = GUIConstants.EDGE_PADDING
|
||||
button_data: list = field(default_factory=lambda: [_("OK")])
|
||||
button_data: list = None
|
||||
allow_text_overflow: bool = False
|
||||
|
||||
|
||||
def __post_init__(self):
|
||||
if not self.button_data:
|
||||
self.button_data = [ButtonOption("OK")]
|
||||
self.is_bottom_list = True
|
||||
super().__post_init__()
|
||||
|
||||
@@ -971,17 +1009,17 @@ class WarningEdgesMixin:
|
||||
|
||||
@dataclass
|
||||
class WarningScreen(WarningEdgesMixin, LargeIconStatusScreen):
|
||||
title: str = _("Caution")
|
||||
title: str = _mft("Caution")
|
||||
status_icon_name: str = SeedSignerIconConstants.WARNING
|
||||
status_color: str = "yellow"
|
||||
status_headline: str = _("Privacy Leak!") # The colored text under the alert icon
|
||||
button_data: list = field(default_factory=lambda: [_("I Understand")])
|
||||
status_headline: str = _mft("Privacy Leak!") # The colored text under the alert icon
|
||||
button_data: list = field(default_factory=lambda: [ButtonOption("I Understand")])
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class DireWarningScreen(WarningScreen):
|
||||
status_headline: str = _("Classified Info!") # The colored text under the alert icon
|
||||
status_headline: str = _mft("Classified Info!") # The colored text under the alert icon
|
||||
status_color: str = GUIConstants.DIRE_WARNING_COLOR
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from seedsigner.gui.renderer import Renderer
|
||||
from seedsigner.helpers.qr import QR
|
||||
from seedsigner.models.threads import BaseThread, ThreadsafeCounter
|
||||
|
||||
from .screen import RET_CODE__BACK_BUTTON, BaseScreen, BaseTopNavScreen, ButtonListScreen, KeyboardScreen, WarningEdgesMixin
|
||||
from .screen import RET_CODE__BACK_BUTTON, BaseScreen, BaseTopNavScreen, ButtonListScreen, ButtonOption, KeyboardScreen, WarningEdgesMixin
|
||||
from ..components import (Button, FontAwesomeIconConstants, Fonts, FormattedAddress, IconButton,
|
||||
IconTextLine, SeedSignerIconConstants, TextArea, GUIConstants, reflow_text_into_pages)
|
||||
|
||||
@@ -607,7 +607,7 @@ class SeedExportXpubDetailsScreen(WarningEdgesMixin, ButtonListScreen):
|
||||
|
||||
def __post_init__(self):
|
||||
# Programmatically set up other args
|
||||
self.button_data = [_("Export Xpub")]
|
||||
self.button_data = [ButtonOption("Export Xpub")]
|
||||
self.title = _("Xpub Details")
|
||||
|
||||
# Initialize the base class
|
||||
@@ -1138,7 +1138,8 @@ class SeedTranscribeSeedQRWholeQRScreen(WarningEdgesMixin, ButtonListScreen):
|
||||
def __post_init__(self):
|
||||
self.title = _("Transcribe SeedQR")
|
||||
# TRANSLATOR_NOTE: Refers to the QR code size: 21x21, 25x25, or 29x29
|
||||
self.button_data = [_("Begin {}x{}").format(self.num_modules, self.num_modules)]
|
||||
button_label = _("Begin {}x{}").format(self.num_modules, self.num_modules)
|
||||
self.button_data = [ButtonOption(button_label)]
|
||||
self.is_bottom_list = True
|
||||
self.status_color = GUIConstants.DIRE_WARNING_COLOR
|
||||
super().__post_init__()
|
||||
@@ -1564,7 +1565,7 @@ class SeedSignMessageConfirmMessageScreen(ButtonListScreen):
|
||||
self.title = f"""Message (pt {self.page_num + 1}/{len(self.sign_message_data["paged_message"])})"""
|
||||
self.is_bottom_list = True
|
||||
self.is_button_text_centered = True
|
||||
self.button_data = [_("Next")]
|
||||
self.button_data = [ButtonOption("Next")]
|
||||
super().__post_init__()
|
||||
|
||||
message_display = TextArea(
|
||||
@@ -1586,7 +1587,7 @@ class SeedSignMessageConfirmAddressScreen(ButtonListScreen):
|
||||
self.title = _("Confirm Address")
|
||||
self.is_bottom_list = True
|
||||
self.is_button_text_centered = True
|
||||
self.button_data = [_("Sign Message")]
|
||||
self.button_data = [ButtonOption("Sign Message")]
|
||||
super().__post_init__()
|
||||
|
||||
derivation_path_display = IconTextLine(
|
||||
|
||||
@@ -5,9 +5,10 @@ from gettext import gettext as _
|
||||
from PIL.ImageOps import autocontrast
|
||||
from typing import List
|
||||
|
||||
from seedsigner.helpers.l10n import mark_for_translation as _mft
|
||||
from seedsigner.gui.components import Button, CheckboxButton, CheckedSelectionButton, FontAwesomeIconConstants, Fonts, GUIConstants, Icon, IconButton, IconTextLine, TextArea
|
||||
from seedsigner.gui.screens.scan_screens import ScanScreen
|
||||
from seedsigner.gui.screens.screen import BaseScreen, BaseTopNavScreen, ButtonListScreen
|
||||
from seedsigner.gui.screens.screen import BaseScreen, BaseTopNavScreen, ButtonListScreen, ButtonOption
|
||||
from seedsigner.hardware.buttons import HardwareButtonsConstants
|
||||
from seedsigner.hardware.camera import Camera
|
||||
from seedsigner.models.settings import SettingsConstants
|
||||
@@ -309,13 +310,13 @@ class DonateScreen(BaseTopNavScreen):
|
||||
@dataclass
|
||||
class SettingsQRConfirmationScreen(ButtonListScreen):
|
||||
config_name: str = None
|
||||
title: str = _("Settings QR")
|
||||
status_message: str = _("Settings updated...")
|
||||
title: str = _mft("Settings QR")
|
||||
status_message: str = _mft("Settings updated...")
|
||||
is_bottom_list: bool = True
|
||||
|
||||
def __post_init__(self):
|
||||
# Customize defaults
|
||||
self.button_data = [_("Home")]
|
||||
self.button_data = [ButtonOption("Home")]
|
||||
self.show_back_button = False
|
||||
super().__post_init__()
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ def get_standard_derivation_path(network: str = SettingsConstants.MAINNET, walle
|
||||
elif script_type == SettingsConstants.NATIVE_SEGWIT:
|
||||
return f"m/48'/{network_path}/0'/2'"
|
||||
elif script_type == SettingsConstants.TAPROOT:
|
||||
raise Exception("Taproot multisig/musig not yet supported")
|
||||
raise Exception("Taproot multisig not yet supported")
|
||||
else:
|
||||
raise Exception("Unexpected script type")
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
def mark_for_translation(message: str) -> str:
|
||||
# Wraps the target string literal for translation but does NOT return the translated string.
|
||||
return message
|
||||
@@ -1,7 +1,7 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, List
|
||||
|
||||
from gettext import gettext as _
|
||||
from seedsigner.helpers.l10n import mark_for_translation as _mft
|
||||
|
||||
|
||||
class SettingsConstants:
|
||||
@@ -11,25 +11,25 @@ class SettingsConstants:
|
||||
OPTION__PROMPT = "P"
|
||||
OPTION__REQUIRED = "R"
|
||||
OPTIONS__ENABLED_DISABLED = [
|
||||
(OPTION__ENABLED, _("Enabled")),
|
||||
(OPTION__DISABLED, _("Disabled")),
|
||||
(OPTION__ENABLED, _mft("Enabled")),
|
||||
(OPTION__DISABLED, _mft("Disabled")),
|
||||
]
|
||||
OPTIONS__ONLY_DISABLED = [
|
||||
(OPTION__DISABLED, _("Disabled")),
|
||||
(OPTION__DISABLED, _mft("Disabled")),
|
||||
]
|
||||
OPTIONS__PROMPT_REQUIRED_DISABLED = [
|
||||
(OPTION__PROMPT, _("Prompt")),
|
||||
(OPTION__REQUIRED, _("Required")),
|
||||
(OPTION__DISABLED, _("Disabled")),
|
||||
(OPTION__PROMPT, _mft("Prompt")),
|
||||
(OPTION__REQUIRED, _mft("Required")),
|
||||
(OPTION__DISABLED, _mft("Disabled")),
|
||||
]
|
||||
OPTIONS__ENABLED_DISABLED_REQUIRED = OPTIONS__ENABLED_DISABLED +[
|
||||
(OPTION__REQUIRED, _("Required")),
|
||||
(OPTION__REQUIRED, _mft("Required")),
|
||||
]
|
||||
OPTIONS__ENABLED_DISABLED_PROMPT = OPTIONS__ENABLED_DISABLED + [
|
||||
(OPTION__PROMPT, _("Prompt")),
|
||||
(OPTION__PROMPT, _mft("Prompt")),
|
||||
]
|
||||
ALL_OPTIONS = OPTIONS__ENABLED_DISABLED_PROMPT + [
|
||||
(OPTION__REQUIRED, _("Required")),
|
||||
(OPTION__REQUIRED, _mft("Required")),
|
||||
]
|
||||
|
||||
# User-facing selection options
|
||||
@@ -77,10 +77,10 @@ class SettingsConstants:
|
||||
BTC_DENOMINATION__THRESHOLD = "thr"
|
||||
BTC_DENOMINATION__BTCSATSHYBRID = "hyb"
|
||||
ALL_BTC_DENOMINATIONS = [
|
||||
(BTC_DENOMINATION__BTC, _("BTC")),
|
||||
(BTC_DENOMINATION__SATS, _("sats")),
|
||||
(BTC_DENOMINATION__THRESHOLD, _("Threshold at 0.01")),
|
||||
(BTC_DENOMINATION__BTCSATSHYBRID, _("BTC | sats hybrid")),
|
||||
(BTC_DENOMINATION__BTC, _mft("BTC")),
|
||||
(BTC_DENOMINATION__SATS, _mft("sats")),
|
||||
(BTC_DENOMINATION__THRESHOLD, _mft("Threshold at 0.01")),
|
||||
(BTC_DENOMINATION__BTCSATSHYBRID, _mft("BTC | sats hybrid")),
|
||||
]
|
||||
|
||||
CAMERA_ROTATION__0 = 0
|
||||
@@ -88,10 +88,10 @@ class SettingsConstants:
|
||||
CAMERA_ROTATION__180 = 180
|
||||
CAMERA_ROTATION__270 = 270
|
||||
ALL_CAMERA_ROTATIONS = [
|
||||
(CAMERA_ROTATION__0, _("0°")),
|
||||
(CAMERA_ROTATION__90, _("90°")),
|
||||
(CAMERA_ROTATION__180, _("180°")),
|
||||
(CAMERA_ROTATION__270, _("270°")),
|
||||
(CAMERA_ROTATION__0, _mft("0°")),
|
||||
(CAMERA_ROTATION__90, _mft("90°")),
|
||||
(CAMERA_ROTATION__180, _mft("180°")),
|
||||
(CAMERA_ROTATION__270, _mft("270°")),
|
||||
]
|
||||
|
||||
# QR code constants
|
||||
@@ -99,11 +99,11 @@ class SettingsConstants:
|
||||
DENSITY__MEDIUM = "M"
|
||||
DENSITY__HIGH = "H"
|
||||
# TRANSLATOR_NOTE: QR code density option: Low, Medium, High
|
||||
density_low = _("Low")
|
||||
density_low = _mft("Low")
|
||||
# TRANSLATOR_NOTE: QR code density option: Low, Medium, High
|
||||
density_medium = _("Medium")
|
||||
density_medium = _mft("Medium")
|
||||
# TRANSLATOR_NOTE: QR code density option: Low, Medium, High
|
||||
density_high = _("High")
|
||||
density_high = _mft("High")
|
||||
ALL_DENSITIES = [
|
||||
(DENSITY__LOW, density_low),
|
||||
(DENSITY__MEDIUM, density_medium),
|
||||
@@ -115,9 +115,9 @@ class SettingsConstants:
|
||||
TESTNET = "T"
|
||||
REGTEST = "R"
|
||||
ALL_NETWORKS = [
|
||||
(MAINNET, _("Mainnet")),
|
||||
(TESTNET, _("Testnet")),
|
||||
(REGTEST, _("Regtest"))
|
||||
(MAINNET, _mft("Mainnet")),
|
||||
(TESTNET, _mft("Testnet")),
|
||||
(REGTEST, _mft("Regtest"))
|
||||
]
|
||||
|
||||
@classmethod
|
||||
@@ -130,14 +130,14 @@ class SettingsConstants:
|
||||
if network == SettingsConstants.REGTEST:
|
||||
return "regtest"
|
||||
|
||||
PERSISTENT_SETTINGS__SD_INSERTED__HELP_TEXT = _("Store Settings on SD card")
|
||||
PERSISTENT_SETTINGS__SD_REMOVED__HELP_TEXT = _("Insert SD card to enable")
|
||||
PERSISTENT_SETTINGS__SD_INSERTED__HELP_TEXT = _mft("Store Settings on SD card")
|
||||
PERSISTENT_SETTINGS__SD_REMOVED__HELP_TEXT = _mft("Insert SD card to enable")
|
||||
|
||||
SINGLE_SIG = "ss"
|
||||
MULTISIG = "ms"
|
||||
ALL_SIG_TYPES = [
|
||||
(SINGLE_SIG, _("Single Sig")),
|
||||
(MULTISIG, _("Multisig")),
|
||||
(SINGLE_SIG, _mft("Single Sig")),
|
||||
(MULTISIG, _mft("Multisig")),
|
||||
]
|
||||
|
||||
LEGACY_P2PKH = "leg"
|
||||
@@ -146,11 +146,11 @@ class SettingsConstants:
|
||||
TAPROOT = "tr"
|
||||
CUSTOM_DERIVATION = "cus"
|
||||
ALL_SCRIPT_TYPES = [
|
||||
(NATIVE_SEGWIT, _("Native Segwit")),
|
||||
(NESTED_SEGWIT, _("Nested Segwit")),
|
||||
(LEGACY_P2PKH, _("Legacy")),
|
||||
(TAPROOT, _("Taproot")),
|
||||
(CUSTOM_DERIVATION, _("Custom Derivation")),
|
||||
(NATIVE_SEGWIT, _mft("Native Segwit")),
|
||||
(NESTED_SEGWIT, _mft("Nested Segwit")),
|
||||
(LEGACY_P2PKH, _mft("Legacy")),
|
||||
(TAPROOT, _mft("Taproot")),
|
||||
(CUSTOM_DERIVATION, _mft("Custom Derivation")),
|
||||
]
|
||||
|
||||
WORDLIST_LANGUAGE__ENGLISH = "en"
|
||||
@@ -237,9 +237,9 @@ class SettingsConstants:
|
||||
ELECTRUM_PBKDF2_ROUNDS=2048
|
||||
|
||||
# Label strings
|
||||
LABEL__BIP39_PASSPHRASE = _("BIP-39 Passphrase")
|
||||
LABEL__BIP39_PASSPHRASE = _mft("BIP-39 Passphrase")
|
||||
# TRANSLATOR_NOTE: Terminology used by Electrum seeds; equivalent to bip39 passphrase
|
||||
custom_extension = _("Custom Extension")
|
||||
custom_extension = _mft("Custom Extension")
|
||||
LABEL__CUSTOM_EXTENSION = custom_extension
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ class SettingsEntry:
|
||||
option_value = option
|
||||
display_name = option
|
||||
if option_value == value:
|
||||
return _(display_name)
|
||||
return _mft(display_name)
|
||||
|
||||
|
||||
def get_selection_option_value_by_display_name(self, display_name: str):
|
||||
@@ -380,7 +380,7 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__SYSTEM,
|
||||
attr_name=SettingsConstants.SETTING__LOCALE,
|
||||
abbreviated_name="lang",
|
||||
display_name=_("Language"),
|
||||
display_name=_mft("Language"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
selection_options=SettingsConstants.ALL_LOCALES,
|
||||
default_value=SettingsConstants.LOCALE__ENGLISH),
|
||||
@@ -389,7 +389,7 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__SYSTEM,
|
||||
attr_name=SettingsConstants.SETTING__WORDLIST_LANGUAGE,
|
||||
abbreviated_name="wordlist_lang",
|
||||
display_name=_("Mnemonic language"),
|
||||
display_name=_mft("Mnemonic language"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
visibility=SettingsConstants.VISIBILITY__HIDDEN,
|
||||
selection_options=SettingsConstants.ALL_WORDLIST_LANGUAGES,
|
||||
@@ -398,14 +398,14 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__SYSTEM,
|
||||
attr_name=SettingsConstants.SETTING__PERSISTENT_SETTINGS,
|
||||
abbreviated_name="persistent",
|
||||
display_name=_("Persistent settings"),
|
||||
display_name=_mft("Persistent settings"),
|
||||
help_text=SettingsConstants.PERSISTENT_SETTINGS__SD_INSERTED__HELP_TEXT,
|
||||
default_value=SettingsConstants.OPTION__DISABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__WALLET,
|
||||
attr_name=SettingsConstants.SETTING__COORDINATORS,
|
||||
abbreviated_name="coords",
|
||||
display_name=_("Coordinator software"),
|
||||
display_name=_mft("Coordinator software"),
|
||||
type=SettingsConstants.TYPE__MULTISELECT,
|
||||
selection_options=SettingsConstants.ALL_COORDINATORS,
|
||||
default_value=[
|
||||
@@ -418,7 +418,7 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__SYSTEM,
|
||||
attr_name=SettingsConstants.SETTING__BTC_DENOMINATION,
|
||||
abbreviated_name="denom",
|
||||
display_name=_("Denomination display"),
|
||||
display_name=_mft("Denomination display"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
selection_options=SettingsConstants.ALL_BTC_DENOMINATIONS,
|
||||
default_value=SettingsConstants.BTC_DENOMINATION__THRESHOLD),
|
||||
@@ -427,7 +427,7 @@ class SettingsDefinition:
|
||||
# Advanced options
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__NETWORK,
|
||||
display_name=_("Bitcoin network"),
|
||||
display_name=_mft("Bitcoin network"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
selection_options=SettingsConstants.ALL_NETWORKS,
|
||||
@@ -435,7 +435,7 @@ class SettingsDefinition:
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__QR_DENSITY,
|
||||
display_name=_("QR code density"),
|
||||
display_name=_mft("QR code density"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
selection_options=SettingsConstants.ALL_DENSITIES,
|
||||
@@ -443,14 +443,14 @@ class SettingsDefinition:
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__XPUB_EXPORT,
|
||||
display_name=_("Xpub export"),
|
||||
display_name=_mft("Xpub export"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__SIG_TYPES,
|
||||
abbreviated_name="sigs",
|
||||
display_name=_("Sig types"),
|
||||
display_name=_mft("Sig types"),
|
||||
type=SettingsConstants.TYPE__MULTISELECT,
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
selection_options=SettingsConstants.ALL_SIG_TYPES,
|
||||
@@ -459,7 +459,7 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__SCRIPT_TYPES,
|
||||
abbreviated_name="scripts",
|
||||
display_name=_("Script types"),
|
||||
display_name=_mft("Script types"),
|
||||
type=SettingsConstants.TYPE__MULTISELECT,
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
selection_options=SettingsConstants.ALL_SCRIPT_TYPES,
|
||||
@@ -467,13 +467,13 @@ class SettingsDefinition:
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__XPUB_DETAILS,
|
||||
display_name=_("Show xpub details"),
|
||||
display_name=_mft("Show xpub details"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__PASSPHRASE,
|
||||
display_name=_("BIP-39 passphrase"),
|
||||
display_name=_mft("BIP-39 passphrase"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
selection_options=SettingsConstants.OPTIONS__ENABLED_DISABLED_REQUIRED,
|
||||
@@ -482,7 +482,7 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__CAMERA_ROTATION,
|
||||
abbreviated_name="camera",
|
||||
display_name=_("Camera rotation"),
|
||||
display_name=_mft("Camera rotation"),
|
||||
type=SettingsConstants.TYPE__SELECT_1,
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
selection_options=SettingsConstants.ALL_CAMERA_ROTATIONS,
|
||||
@@ -490,14 +490,14 @@ class SettingsDefinition:
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__COMPACT_SEEDQR,
|
||||
display_name=_("Compact SeedQR"),
|
||||
display_name=_mft("Compact SeedQR"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__BIP85_CHILD_SEEDS,
|
||||
abbreviated_name="bip85",
|
||||
display_name=_("BIP-85 child seeds"),
|
||||
display_name=_mft("BIP-85 child seeds"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__DISABLED),
|
||||
|
||||
@@ -505,40 +505,40 @@ class SettingsDefinition:
|
||||
attr_name=SettingsConstants.SETTING__ELECTRUM_SEEDS,
|
||||
abbreviated_name="electrum",
|
||||
display_name="Electrum seeds",
|
||||
help_text=_("Native Segwit only"),
|
||||
help_text=_mft("Native Segwit only"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__DISABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__MESSAGE_SIGNING,
|
||||
display_name=_("Message signing"),
|
||||
display_name=_mft("Message signing"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__DISABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__PRIVACY_WARNINGS,
|
||||
abbreviated_name="priv_warn",
|
||||
display_name=_("Show privacy warnings"),
|
||||
display_name=_mft("Show privacy warnings"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__DIRE_WARNINGS,
|
||||
abbreviated_name="dire_warn",
|
||||
display_name=_("Show dire warnings"),
|
||||
display_name=_mft("Show dire warnings"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__QR_BRIGHTNESS_TIPS,
|
||||
display_name=_("Show QR brightness tips"),
|
||||
display_name=_mft("Show QR brightness tips"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__FEATURES,
|
||||
attr_name=SettingsConstants.SETTING__PARTNER_LOGOS,
|
||||
abbreviated_name="partners",
|
||||
display_name=_("Show partner logos"),
|
||||
display_name=_mft("Show partner logos"),
|
||||
visibility=SettingsConstants.VISIBILITY__ADVANCED,
|
||||
default_value=SettingsConstants.OPTION__ENABLED),
|
||||
|
||||
@@ -554,7 +554,7 @@ class SettingsDefinition:
|
||||
SettingsEntry(category=SettingsConstants.CATEGORY__SYSTEM,
|
||||
attr_name=SettingsConstants.SETTING__QR_BRIGHTNESS,
|
||||
abbreviated_name="qr_brightness",
|
||||
display_name=_("QR background color"),
|
||||
display_name=_mft("QR background color"),
|
||||
type=SettingsConstants.TYPE__FREE_ENTRY,
|
||||
visibility=SettingsConstants.VISIBILITY__HIDDEN,
|
||||
default_value=62),
|
||||
|
||||
@@ -3,16 +3,16 @@ from gettext import gettext as _
|
||||
from seedsigner.models.psbt_parser import PSBTParser
|
||||
from seedsigner.models.settings import SettingsConstants
|
||||
from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants
|
||||
from seedsigner.gui.screens.screen import (RET_CODE__BACK_BUTTON, ButtonListScreen, WarningScreen, DireWarningScreen, QRDisplayScreen)
|
||||
from seedsigner.gui.screens.screen import (RET_CODE__BACK_BUTTON, ButtonListScreen, ButtonOption, WarningScreen, DireWarningScreen, QRDisplayScreen)
|
||||
from seedsigner.views.view import BackStackView, MainMenuView, NotYetImplementedView, View, Destination
|
||||
|
||||
|
||||
|
||||
class PSBTSelectSeedView(View):
|
||||
SCAN_SEED = (_("Scan a seed"), SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = (_("Enter 12-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = (_("Enter 24-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = (_("Enter Electrum seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
SCAN_SEED = ButtonOption("Scan a seed", SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = ButtonOption("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ButtonOption("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = ButtonOption("Enter Electrum seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
|
||||
|
||||
def run(self):
|
||||
@@ -38,7 +38,7 @@ class PSBTSelectSeedView(View):
|
||||
# TRANSLATOR_NOTE: Inserts fingerprint w/"?" to indicate that this seed can't sign the current PSBT
|
||||
button_str = _("{} (?)").format(button_str)
|
||||
|
||||
button_data.append((button_str, SeedSignerIconConstants.FINGERPRINT))
|
||||
button_data.append(ButtonOption(button_str, SeedSignerIconConstants.FINGERPRINT))
|
||||
|
||||
button_data.append(self.SCAN_SEED)
|
||||
button_data.append(self.TYPE_12WORD)
|
||||
@@ -169,7 +169,7 @@ class PSBTUnsupportedScriptTypeWarningView(View):
|
||||
selected_menu_num = WarningScreen(
|
||||
status_headline=_("Unsupported Script Type!"),
|
||||
text=_("PSBT has unsupported input script type, please verify your change addresses."),
|
||||
button_data=[_("Continue")],
|
||||
button_data=[ButtonOption("Continue")],
|
||||
).display()
|
||||
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
@@ -190,7 +190,7 @@ class PSBTNoChangeWarningView(View):
|
||||
# TRANSLATOR_NOTE: User will receive no change back; the inputs to this transaction are fully spent
|
||||
status_headline=_("Full Spend!"),
|
||||
text=_("This PSBT spends its entire input value. No change is coming back to your wallet."),
|
||||
button_data=[_("Continue")],
|
||||
button_data=[ButtonOption("Continue")],
|
||||
).display()
|
||||
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
@@ -265,10 +265,10 @@ class PSBTAddressDetailsView(View):
|
||||
|
||||
button_data = []
|
||||
if self.address_num < psbt_parser.num_destinations - 1:
|
||||
button_data.append(_("Next Recipient"))
|
||||
button_data.append(ButtonOption("Next Recipient"))
|
||||
else:
|
||||
# TRANSLATOR_NOTE: Short for "Next step"
|
||||
button_data.append(_("Next"))
|
||||
button_data.append(ButtonOption("Next"))
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
PSBTAddressDetailsScreen,
|
||||
@@ -299,10 +299,9 @@ class PSBTAddressDetailsView(View):
|
||||
|
||||
|
||||
class PSBTChangeDetailsView(View):
|
||||
NEXT = _("Next")
|
||||
SKIP_VERIFICATION = _("Skip Verification")
|
||||
VERIFY_MULTISIG = _("Verify Multisig Change")
|
||||
|
||||
NEXT = ButtonOption("Next")
|
||||
SKIP_VERIFICATION = ButtonOption("Skip Verification")
|
||||
VERIFY_MULTISIG = ButtonOption("Verify Multisig Change")
|
||||
|
||||
def __init__(self, change_address_num):
|
||||
super().__init__()
|
||||
@@ -349,7 +348,7 @@ class PSBTChangeDetailsView(View):
|
||||
title = _("Your Change")
|
||||
else:
|
||||
title = _("Self-Transfer")
|
||||
self.VERIFY_MULTISIG = _("Verify Multisig Addr")
|
||||
self.VERIFY_MULTISIG.button_label = _("Verify Multisig Addr")
|
||||
# if psbt_parser.num_change_outputs > 1:
|
||||
# title += f" (#{self.change_address_num + 1})"
|
||||
|
||||
@@ -473,7 +472,7 @@ class PSBTAddressVerificationFailedView(View):
|
||||
title=title,
|
||||
status_headline=_("Address Verification Failed"),
|
||||
text=text,
|
||||
button_data=[_("Discard PSBT")],
|
||||
button_data=[ButtonOption("Discard PSBT")],
|
||||
show_back_button=False,
|
||||
).display()
|
||||
|
||||
@@ -495,8 +494,8 @@ class PSBTOpReturnView(View):
|
||||
# Should not be able to get here
|
||||
raise Exception("Routing error")
|
||||
|
||||
title = "OP_RETURN"
|
||||
button_data = ["Next"]
|
||||
title = _("OP_RETURN")
|
||||
button_data = [ButtonOption("Next")]
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
PSBTOpReturnScreen,
|
||||
@@ -515,7 +514,7 @@ class PSBTOpReturnView(View):
|
||||
class PSBTFinalizeView(View):
|
||||
"""
|
||||
"""
|
||||
APPROVE_PSBT = "Approve PSBT"
|
||||
APPROVE_PSBT = ButtonOption("Approve PSBT")
|
||||
|
||||
|
||||
def run(self):
|
||||
@@ -524,7 +523,6 @@ class PSBTFinalizeView(View):
|
||||
|
||||
psbt_parser: PSBTParser = self.controller.psbt_parser
|
||||
psbt: PSBT = self.controller.psbt
|
||||
self.APPROVE_PSBT = _("Approve PSBT")
|
||||
|
||||
if not psbt_parser:
|
||||
# Should not be able to get here
|
||||
@@ -573,7 +571,7 @@ class PSBTSignedQRDisplayView(View):
|
||||
|
||||
|
||||
class PSBTSigningErrorView(View):
|
||||
SELECT_DIFF_SEED = _("Select Diff Seed")
|
||||
SELECT_DIFF_SEED = ButtonOption("Select Diff Seed")
|
||||
|
||||
def run(self):
|
||||
psbt_parser: PSBTParser = self.controller.psbt_parser
|
||||
|
||||
@@ -2,7 +2,7 @@ import logging
|
||||
import re
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
from seedsigner.helpers.l10n import mark_for_translation as _mft
|
||||
from seedsigner.models.settings import SettingsConstants
|
||||
from seedsigner.views.view import BackStackView, ErrorView, MainMenuView, NotYetImplementedView, View, Destination
|
||||
|
||||
@@ -19,8 +19,8 @@ class ScanView(View):
|
||||
dedicated errors when an unexpected QR type is scanned (e.g. Scan PSBT was
|
||||
selected but a SeedQR was scanned).
|
||||
"""
|
||||
instructions_text = _("Scan a QR code")
|
||||
invalid_qr_type_message = _("QRCode not recognized or not yet supported.")
|
||||
instructions_text = _mft("Scan a QR code")
|
||||
invalid_qr_type_message = _mft("QRCode not recognized or not yet supported.")
|
||||
|
||||
|
||||
def __init__(self):
|
||||
@@ -176,8 +176,8 @@ class ScanView(View):
|
||||
|
||||
|
||||
class ScanPSBTView(ScanView):
|
||||
instructions_text = _("Scan PSBT")
|
||||
invalid_qr_type_message = _("Expected a PSBT")
|
||||
instructions_text = _mft("Scan PSBT")
|
||||
invalid_qr_type_message = _mft("Expected a PSBT")
|
||||
|
||||
@property
|
||||
def is_valid_qr_type(self):
|
||||
@@ -186,8 +186,8 @@ class ScanPSBTView(ScanView):
|
||||
|
||||
|
||||
class ScanSeedQRView(ScanView):
|
||||
instructions_text = _("Scan SeedQR")
|
||||
invalid_qr_type_message = _("Expected a SeedQR")
|
||||
instructions_text = _mft("Scan SeedQR")
|
||||
invalid_qr_type_message = _mft("Expected a SeedQR")
|
||||
|
||||
@property
|
||||
def is_valid_qr_type(self):
|
||||
@@ -196,8 +196,8 @@ class ScanSeedQRView(ScanView):
|
||||
|
||||
|
||||
class ScanWalletDescriptorView(ScanView):
|
||||
instructions_text = _("Scan descriptor")
|
||||
invalid_qr_type_message = _("Expected a wallet descriptor QR")
|
||||
instructions_text = _mft("Scan descriptor")
|
||||
invalid_qr_type_message = _mft("Expected a wallet descriptor QR")
|
||||
|
||||
@property
|
||||
def is_valid_qr_type(self):
|
||||
@@ -206,8 +206,8 @@ class ScanWalletDescriptorView(ScanView):
|
||||
|
||||
|
||||
class ScanAddressView(ScanView):
|
||||
instructions_text = _("Scan address QR")
|
||||
invalid_qr_type_message = _("Expected an address QR")
|
||||
instructions_text = _mft("Scan address QR")
|
||||
invalid_qr_type_message = _mft("Expected an address QR")
|
||||
|
||||
@property
|
||||
def is_valid_qr_type(self):
|
||||
|
||||
@@ -10,6 +10,7 @@ from embit.descriptor import Descriptor
|
||||
from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants
|
||||
from seedsigner.gui.screens import (RET_CODE__BACK_BUTTON, ButtonListScreen,
|
||||
WarningScreen, DireWarningScreen, seed_screens)
|
||||
from seedsigner.gui.screens.screen import ButtonOption
|
||||
from seedsigner.models.encode_qr import CompactSeedQrEncoder, GenericStaticQrEncoder, SeedQrEncoder, SpecterXPubQrEncoder, StaticXpubQrEncoder, UrXpubQrEncoder
|
||||
from seedsigner.models.qr_type import QRType
|
||||
from seedsigner.models.seed import Seed
|
||||
@@ -23,7 +24,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SeedsMenuView(View):
|
||||
LOAD = "Load a seed"
|
||||
LOAD = ButtonOption("Load a seed")
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -41,8 +42,8 @@ class SeedsMenuView(View):
|
||||
|
||||
button_data = []
|
||||
for seed in self.seeds:
|
||||
button_data.append((seed["fingerprint"], SeedSignerIconConstants.FINGERPRINT))
|
||||
button_data.append(_("Load a seed"))
|
||||
button_data.append(ButtonOption(seed["fingerprint"], SeedSignerIconConstants.FINGERPRINT))
|
||||
button_data.append(self.LOAD)
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
@@ -54,7 +55,7 @@ class SeedsMenuView(View):
|
||||
if len(self.seeds) > 0 and selected_menu_num < len(self.seeds):
|
||||
return Destination(SeedOptionsView, view_args={"seed_num": selected_menu_num})
|
||||
|
||||
elif selected_menu_num == len(self.seeds):
|
||||
elif button_data[selected_menu_num] == self.LOAD:
|
||||
return Destination(LoadSeedView)
|
||||
|
||||
elif selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
@@ -70,10 +71,10 @@ class SeedSelectSeedView(View):
|
||||
* `flow`: indicates which user flow is in progress during seed selection (e.g.
|
||||
verify single sig addr or sign message).
|
||||
"""
|
||||
SCAN_SEED = (_("Scan a seed"), SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = (_("Enter 12-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = (_("Enter 24-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = (_("Enter Electrum seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
SCAN_SEED = ButtonOption("Scan a seed", SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = ButtonOption("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ButtonOption("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = ButtonOption("Enter Electrum seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
|
||||
|
||||
def __init__(self, flow: str = None):
|
||||
@@ -108,11 +109,7 @@ class SeedSelectSeedView(View):
|
||||
button_data = []
|
||||
for seed in seeds:
|
||||
button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK))
|
||||
|
||||
if seed.passphrase is not None:
|
||||
# TODO: Include lock icon on right side of button
|
||||
pass
|
||||
button_data.append((button_str, SeedSignerIconConstants.FINGERPRINT, "blue"))
|
||||
button_data.append(ButtonOption(button_str, SeedSignerIconConstants.FINGERPRINT, icon_color="blue"))
|
||||
|
||||
button_data.append(self.SCAN_SEED)
|
||||
button_data.append(self.TYPE_12WORD)
|
||||
@@ -165,11 +162,11 @@ class SeedSelectSeedView(View):
|
||||
Loading seeds, passphrases, etc
|
||||
****************************************************************************"""
|
||||
class LoadSeedView(View):
|
||||
SEED_QR = (_("Scan a SeedQR"), SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = (_("Enter 12-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = (_("Enter 24-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = (_("Enter Electrum seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
CREATE = (_(" Create a seed"), SeedSignerIconConstants.PLUS)
|
||||
SEED_QR = ButtonOption("Scan a SeedQR", SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = ButtonOption("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ButtonOption("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = ButtonOption("Enter Electrum seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
CREATE = ButtonOption(" Create a seed", SeedSignerIconConstants.PLUS)
|
||||
|
||||
def run(self):
|
||||
button_data = [
|
||||
@@ -274,8 +271,8 @@ class SeedMnemonicEntryView(View):
|
||||
|
||||
|
||||
class SeedMnemonicInvalidView(View):
|
||||
EDIT = _("Review & Edit")
|
||||
DISCARD = (_("Discard"), None, None, "red")
|
||||
EDIT = ButtonOption("Review & Edit")
|
||||
DISCARD = ButtonOption("Discard", button_label_color="red")
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -303,8 +300,8 @@ class SeedMnemonicInvalidView(View):
|
||||
|
||||
|
||||
class SeedFinalizeView(View):
|
||||
FINALIZE = _("Done")
|
||||
PASSPHRASE = _("BIP-39 Passphrase")
|
||||
FINALIZE = ButtonOption("Done")
|
||||
PASSPHRASE = ButtonOption("BIP-39 Passphrase")
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -327,9 +324,9 @@ class SeedFinalizeView(View):
|
||||
|
||||
def run(self):
|
||||
button_data = [self.FINALIZE]
|
||||
passphrase_button = self.seed.passphrase_label
|
||||
self.PASSPHRASE.button_label = self.seed.passphrase_label
|
||||
if self.settings.get_value(SettingsConstants.SETTING__PASSPHRASE) != SettingsConstants.OPTION__DISABLED:
|
||||
button_data.append(passphrase_button)
|
||||
button_data.append(self.PASSPHRASE)
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
seed_screens.SeedFinalizeScreen,
|
||||
@@ -341,7 +338,7 @@ class SeedFinalizeView(View):
|
||||
seed_num = self.controller.storage.finalize_pending_seed()
|
||||
return Destination(SeedOptionsView, view_args={"seed_num": seed_num}, clear_history=True)
|
||||
|
||||
elif button_data[selected_menu_num] == passphrase_button:
|
||||
elif button_data[selected_menu_num] == self.PASSPHRASE:
|
||||
return Destination(SeedAddPassphraseView)
|
||||
|
||||
elif selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
@@ -377,8 +374,8 @@ class SeedAddPassphraseView(View):
|
||||
|
||||
|
||||
class SeedAddPassphraseExitDialogView(View):
|
||||
EDIT = _("Edit passphrase")
|
||||
DISCARD = (_("Discard passphrase"), None, None, "red")
|
||||
EDIT = ButtonOption("Edit passphrase")
|
||||
DISCARD = ButtonOption("Discard passphrase", button_label_color="red")
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -410,8 +407,8 @@ class SeedReviewPassphraseView(View):
|
||||
"""
|
||||
Display the completed passphrase back to the user.
|
||||
"""
|
||||
EDIT = _("Edit passphrase")
|
||||
DONE = _("Done")
|
||||
EDIT = ButtonOption("Edit passphrase")
|
||||
DONE = ButtonOption("Done")
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -450,8 +447,8 @@ class SeedReviewPassphraseView(View):
|
||||
|
||||
|
||||
class SeedDiscardView(View):
|
||||
KEEP = _("Keep Seed")
|
||||
DISCARD = (_("Discard"), None, None, "red")
|
||||
KEEP = ButtonOption("Keep Seed")
|
||||
DISCARD = ButtonOption("Discard", button_label_color="red")
|
||||
|
||||
def __init__(self, seed_num: int = None):
|
||||
super().__init__()
|
||||
@@ -518,14 +515,14 @@ class SeedElectrumMnemonicStartView(View):
|
||||
Views for actions on individual seeds:
|
||||
****************************************************************************"""
|
||||
class SeedOptionsView(View):
|
||||
SCAN_PSBT = (_("Scan PSBT"), SeedSignerIconConstants.QRCODE)
|
||||
VERIFY_ADDRESS = _("Verify Addr")
|
||||
EXPORT_XPUB = _("Export Xpub")
|
||||
EXPLORER = _("Address Explorer")
|
||||
SIGN_MESSAGE = _("Sign Message")
|
||||
BACKUP = (_("Backup Seed"), None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT)
|
||||
BIP85_CHILD_SEED = _("BIP-85 Child Seed")
|
||||
DISCARD = (_("Discard Seed"), None, None, "red")
|
||||
SCAN_PSBT = ButtonOption("Scan PSBT", SeedSignerIconConstants.QRCODE)
|
||||
VERIFY_ADDRESS = ButtonOption("Verify Addr")
|
||||
EXPORT_XPUB = ButtonOption("Export Xpub")
|
||||
EXPLORER = ButtonOption("Address Explorer")
|
||||
SIGN_MESSAGE = ButtonOption("Sign Message")
|
||||
BACKUP = ButtonOption("Backup Seed", right_icon_name=SeedSignerIconConstants.CHEVRON_RIGHT)
|
||||
BIP85_CHILD_SEED = ButtonOption("BIP-85 Child Seed")
|
||||
DISCARD = ButtonOption("Discard Seed", button_label_color="red")
|
||||
|
||||
|
||||
def __init__(self, seed_num: int):
|
||||
@@ -630,8 +627,8 @@ class SeedOptionsView(View):
|
||||
|
||||
|
||||
class SeedBackupView(View):
|
||||
VIEW_WORDS = _("View Seed Words")
|
||||
EXPORT_SEEDQR = _("Export as SeedQR")
|
||||
VIEW_WORDS = ButtonOption("View Seed Words")
|
||||
EXPORT_SEEDQR = ButtonOption("Export as SeedQR")
|
||||
|
||||
def __init__(self, seed_num):
|
||||
super().__init__()
|
||||
@@ -667,8 +664,8 @@ class SeedBackupView(View):
|
||||
Export Xpub flow
|
||||
****************************************************************************"""
|
||||
class SeedExportXpubSigTypeView(View):
|
||||
SINGLE_SIG = _("Single Sig")
|
||||
MULTISIG = _("Multisig")
|
||||
SINGLE_SIG = ButtonOption("Single Sig", return_data=SettingsConstants.SINGLE_SIG)
|
||||
MULTISIG = ButtonOption("Multisig", return_data=SettingsConstants.MULTISIG)
|
||||
|
||||
def __init__(self, seed_num: int):
|
||||
super().__init__()
|
||||
@@ -680,7 +677,7 @@ class SeedExportXpubSigTypeView(View):
|
||||
# Nothing to select; skip this screen
|
||||
return Destination(SeedExportXpubScriptTypeView, view_args={"seed_num": self.seed_num, "sig_type": self.settings.get_value(SettingsConstants.SETTING__SIG_TYPES)[0]}, skip_current_view=True)
|
||||
|
||||
button_data=[self.SINGLE_SIG, self.MULTISIG]
|
||||
button_data = [self.SINGLE_SIG, self.MULTISIG]
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
@@ -691,11 +688,7 @@ class SeedExportXpubSigTypeView(View):
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
if button_data[selected_menu_num] == self.SINGLE_SIG:
|
||||
return Destination(SeedExportXpubScriptTypeView, view_args={"seed_num": self.seed_num, "sig_type": SettingsConstants.SINGLE_SIG})
|
||||
|
||||
elif button_data[selected_menu_num] == self.MULTISIG:
|
||||
return Destination(SeedExportXpubScriptTypeView, view_args={"seed_num": self.seed_num, "sig_type": SettingsConstants.MULTISIG})
|
||||
return Destination(SeedExportXpubScriptTypeView, view_args={"seed_num": self.seed_num, "sig_type": button_data[selected_menu_num].return_data})
|
||||
|
||||
|
||||
|
||||
@@ -737,13 +730,13 @@ class SeedExportXpubScriptTypeView(View):
|
||||
button_data = []
|
||||
for script_type, display_name in SettingsConstants.ALL_SCRIPT_TYPES:
|
||||
if script_type in self.settings.get_value(SettingsConstants.SETTING__SCRIPT_TYPES):
|
||||
button_data.append((script_type, display_name))
|
||||
button_data.append(ButtonOption(display_name, return_data=script_type))
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
title=title,
|
||||
is_button_text_centered=False,
|
||||
button_data=[x[1] for x in button_data],
|
||||
button_data=button_data,
|
||||
is_bottom_list=True,
|
||||
)
|
||||
|
||||
@@ -754,7 +747,7 @@ class SeedExportXpubScriptTypeView(View):
|
||||
return Destination(BackStackView)
|
||||
|
||||
else:
|
||||
args["script_type"] = button_data[selected_menu_num][0]
|
||||
args["script_type"] = button_data[selected_menu_num].return_data
|
||||
|
||||
if args["script_type"] == SettingsConstants.CUSTOM_DERIVATION:
|
||||
return Destination(SeedExportXpubCustomDerivationView, view_args=args)
|
||||
@@ -826,7 +819,9 @@ class SeedExportXpubCoordinatorView(View):
|
||||
args["coordinator"] = self.settings.get_value(SettingsConstants.SETTING__COORDINATORS)[0]
|
||||
return Destination(SeedExportXpubWarningView, view_args=args, skip_current_view=True)
|
||||
|
||||
button_data = self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__COORDINATORS)
|
||||
button_data = []
|
||||
for display_name, setting_option in zip(self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__COORDINATORS), self.settings.get_value(SettingsConstants.SETTING__COORDINATORS)):
|
||||
button_data.append(ButtonOption(display_name, return_data=setting_option))
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
@@ -838,9 +833,10 @@ class SeedExportXpubCoordinatorView(View):
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
coordinators_settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__COORDINATORS)
|
||||
selected_display_name = button_data[selected_menu_num]
|
||||
args["coordinator"] = coordinators_settings_entry.get_selection_option_value_by_display_name(selected_display_name)
|
||||
# coordinators_settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__COORDINATORS)
|
||||
# selected_display_name = button_data[selected_menu_num]
|
||||
# args["coordinator"] = coordinators_settings_entry.get_selection_option_value_by_display_name(selected_display_name)
|
||||
args["coordinator"] = button_data[selected_menu_num].return_data
|
||||
|
||||
return Destination(SeedExportXpubWarningView, view_args=args)
|
||||
|
||||
@@ -1048,8 +1044,8 @@ class SeedWordsWarningView(View):
|
||||
|
||||
|
||||
class SeedWordsView(View):
|
||||
NEXT = _("Next")
|
||||
DONE = _("Done")
|
||||
NEXT = ButtonOption("Next")
|
||||
DONE = ButtonOption("Done")
|
||||
|
||||
def __init__(self, seed_num: int, bip85_data: dict = None, page_index: int = 0):
|
||||
super().__init__()
|
||||
@@ -1126,14 +1122,14 @@ class SeedBIP85ApplicationModeView(View):
|
||||
* XPRV (BIP32)
|
||||
"""
|
||||
# TODO: Future enhancement to display WIF (HD-SEED) and XPRV (Bip32)?
|
||||
WORDS_12 = _("12 Words")
|
||||
WORDS_24 = _("24 Words")
|
||||
WORDS_12 = ButtonOption("12 Words")
|
||||
WORDS_24 = ButtonOption("24 Words")
|
||||
|
||||
def __init__(self, seed_num: int):
|
||||
super().__init__()
|
||||
self.seed_num = seed_num
|
||||
self.num_words = 0
|
||||
self.bip85_app_num = 39 # TODO: Support other Application numbers
|
||||
self.bip85_app_num = 39 # TODO: Support other Application numbers; TODO: Define this as a constant
|
||||
|
||||
|
||||
def run(self):
|
||||
@@ -1159,8 +1155,8 @@ class SeedBIP85ApplicationModeView(View):
|
||||
|
||||
|
||||
|
||||
# View to retrieve the derived seed index
|
||||
class SeedBIP85SelectChildIndexView(View):
|
||||
# View to retrieve the derived seed index
|
||||
def __init__(self, seed_num: int, num_words: int):
|
||||
super().__init__()
|
||||
self.seed_num = seed_num
|
||||
@@ -1168,7 +1164,7 @@ class SeedBIP85SelectChildIndexView(View):
|
||||
|
||||
|
||||
def run(self):
|
||||
# Change this later to use the generic Screen input keyboard
|
||||
# TODO: Change this later to use the generic Screen input keyboard
|
||||
ret = seed_screens.SeedBIP85SelectChildIndexScreen().display()
|
||||
|
||||
if ret == RET_CODE__BACK_BUTTON:
|
||||
@@ -1206,7 +1202,7 @@ class SeedBIP85InvalidChildIndexView(View):
|
||||
show_back_button=False,
|
||||
status_headline=_("Invalid Child Index"),
|
||||
text=_("BIP-85 Child Index must be between 0 and 2^31-1."),
|
||||
button_data=[_("Try Again")]
|
||||
button_data=[ButtonOption("Try Again")]
|
||||
).display()
|
||||
|
||||
return Destination(
|
||||
@@ -1224,8 +1220,8 @@ class SeedBIP85InvalidChildIndexView(View):
|
||||
Seed Words Backup Test
|
||||
****************************************************************************"""
|
||||
class SeedWordsBackupTestPromptView(View):
|
||||
VERIFY = _("Verify")
|
||||
SKIP = _("Skip")
|
||||
VERIFY = ButtonOption("Verify")
|
||||
SKIP = ButtonOption("Skip")
|
||||
|
||||
def __init__(self, seed_num: int, bip85_data: dict = None):
|
||||
super().__init__()
|
||||
@@ -1283,10 +1279,10 @@ class SeedWordsBackupTestView(View):
|
||||
while self.cur_index in self.confirmed_list:
|
||||
self.cur_index = int(random.random() * len(self.mnemonic_list))
|
||||
|
||||
real_word = self.mnemonic_list[self.cur_index]
|
||||
fake_word1 = bip39.WORDLIST[int(random.random() * 2047)]
|
||||
fake_word2 = bip39.WORDLIST[int(random.random() * 2047)]
|
||||
fake_word3 = bip39.WORDLIST[int(random.random() * 2047)]
|
||||
real_word = ButtonOption(self.mnemonic_list[self.cur_index])
|
||||
fake_word1 = ButtonOption(bip39.WORDLIST[int(random.random() * 2047)])
|
||||
fake_word2 = ButtonOption(bip39.WORDLIST[int(random.random() * 2047)])
|
||||
fake_word3 = ButtonOption(bip39.WORDLIST[int(random.random() * 2047)])
|
||||
|
||||
button_data = [real_word, fake_word1, fake_word2, fake_word3]
|
||||
random.shuffle(button_data)
|
||||
@@ -1332,8 +1328,8 @@ class SeedWordsBackupTestView(View):
|
||||
|
||||
|
||||
class SeedWordsBackupTestMistakeView(View):
|
||||
REVIEW = _("Review Seed Words")
|
||||
RETRY = _("Try Again")
|
||||
REVIEW = ButtonOption("Review Seed Words")
|
||||
RETRY = ButtonOption("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):
|
||||
super().__init__()
|
||||
@@ -1392,7 +1388,7 @@ class SeedWordsBackupTestSuccessView(View):
|
||||
show_back_button=False,
|
||||
status_headline=_("Success!"),
|
||||
text=_("All mnemonic backup words were successfully verified!"),
|
||||
button_data=[_("OK")]
|
||||
button_data=[ButtonOption("OK")]
|
||||
).display()
|
||||
|
||||
if self.seed_num is not None:
|
||||
@@ -1414,15 +1410,11 @@ class SeedTranscribeSeedQRFormatView(View):
|
||||
def run(self):
|
||||
seed = self.controller.get_seed(self.seed_num)
|
||||
if len(seed.mnemonic_list) == 12:
|
||||
STANDARD = _("Standard: 25x25")
|
||||
COMPACT = _("Compact: 21x21")
|
||||
num_modules_standard = 25
|
||||
num_modules_compact = 21
|
||||
STANDARD = ButtonOption("Standard: 25x25", return_data=25)
|
||||
COMPACT = ButtonOption("Compact: 21x21", return_data=21)
|
||||
else:
|
||||
STANDARD = _("Standard: 29x29")
|
||||
COMPACT = _("Compact: 25x25")
|
||||
num_modules_standard = 29
|
||||
num_modules_compact = 25
|
||||
STANDARD = ButtonOption("Standard: 29x29", return_data=29)
|
||||
COMPACT = ButtonOption("Compact: 25x25", return_data=25)
|
||||
|
||||
if self.settings.get_value(SettingsConstants.SETTING__COMPACT_SEEDQR) != SettingsConstants.OPTION__ENABLED:
|
||||
# Only configured for standard SeedQR
|
||||
@@ -1431,7 +1423,7 @@ class SeedTranscribeSeedQRFormatView(View):
|
||||
view_args={
|
||||
"seed_num": self.seed_num,
|
||||
"seedqr_format": QRType.SEED__SEEDQR,
|
||||
"num_modules": num_modules_standard,
|
||||
"num_modules": STANDARD.return_data,
|
||||
},
|
||||
skip_current_view=True,
|
||||
)
|
||||
@@ -1450,10 +1442,10 @@ class SeedTranscribeSeedQRFormatView(View):
|
||||
|
||||
if button_data[selected_menu_num] == STANDARD:
|
||||
seedqr_format = QRType.SEED__SEEDQR
|
||||
num_modules = num_modules_standard
|
||||
else:
|
||||
seedqr_format = QRType.SEED__COMPACTSEEDQR
|
||||
num_modules = num_modules_compact
|
||||
|
||||
num_modules = button_data[selected_menu_num].return_data
|
||||
|
||||
return Destination(
|
||||
SeedTranscribeSeedQRWarningView,
|
||||
@@ -1580,8 +1572,8 @@ class SeedTranscribeSeedQRZoomedInView(View):
|
||||
|
||||
|
||||
class SeedTranscribeSeedQRConfirmQRPromptView(View):
|
||||
SCAN = (_("Confirm SeedQR"), SeedSignerIconConstants.QRCODE)
|
||||
DONE = _("Done")
|
||||
SCAN = ButtonOption("Confirm SeedQR", SeedSignerIconConstants.QRCODE)
|
||||
DONE = ButtonOption("Done")
|
||||
|
||||
def __init__(self, seed_num: int):
|
||||
super().__init__()
|
||||
@@ -1726,8 +1718,8 @@ class AddressVerificationStartView(View):
|
||||
|
||||
|
||||
class AddressVerificationSigTypeView(View):
|
||||
SINGLE_SIG = _("Single Sig")
|
||||
MULTISIG = _("Multisig")
|
||||
SINGLE_SIG = ButtonOption("Single Sig")
|
||||
MULTISIG = ButtonOption("Multisig")
|
||||
|
||||
def run(self):
|
||||
from seedsigner.helpers import embit_utils
|
||||
@@ -1781,8 +1773,8 @@ class SeedAddressVerificationView(View):
|
||||
multisig.
|
||||
"""
|
||||
# TRANSLATOR_NOTE: Option when scanning for a matching address; skips ten addresses ahead
|
||||
SKIP_10 = _("Skip 10")
|
||||
CANCEL = _("Cancel")
|
||||
SKIP_10 = ButtonOption("Skip 10")
|
||||
CANCEL = ButtonOption("Cancel")
|
||||
|
||||
def __init__(self, seed_num: int = None):
|
||||
super().__init__()
|
||||
@@ -2000,8 +1992,8 @@ class AddressVerificationSuccessView(View):
|
||||
|
||||
|
||||
class LoadMultisigWalletDescriptorView(View):
|
||||
SCAN = (_("Scan Descriptor"), SeedSignerIconConstants.QRCODE)
|
||||
CANCEL = _("Cancel")
|
||||
SCAN = ButtonOption("Scan Descriptor", SeedSignerIconConstants.QRCODE)
|
||||
CANCEL = ButtonOption("Cancel")
|
||||
|
||||
def run(self):
|
||||
button_data = [self.SCAN, self.CANCEL]
|
||||
@@ -2025,10 +2017,10 @@ class LoadMultisigWalletDescriptorView(View):
|
||||
|
||||
|
||||
class MultisigWalletDescriptorView(View):
|
||||
RETURN = _("Return to PSBT")
|
||||
VERIFY_ADDR = _("Verify Addr")
|
||||
ADDRESS_EXPLORER = _("Address Explorer")
|
||||
OK = _("OK")
|
||||
RETURN = ButtonOption("Return to PSBT")
|
||||
VERIFY_ADDR = ButtonOption("Verify Addr")
|
||||
ADDRESS_EXPLORER = ButtonOption("Address Explorer")
|
||||
OK = ButtonOption("OK")
|
||||
|
||||
def run(self):
|
||||
descriptor = self.controller.multisig_wallet_descriptor
|
||||
@@ -2047,8 +2039,8 @@ class MultisigWalletDescriptorView(View):
|
||||
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:
|
||||
verify_addr_display = f"""{self.VERIFY_ADDR} {self.controller.unverified_address["address"][:7]}"""
|
||||
button_data = [verify_addr_display]
|
||||
verify_addr_display = f"""{_(self.VERIFY_ADDR.button_label)} {self.controller.unverified_address["address"][:7]}"""
|
||||
button_data = [ButtonOption(verify_addr_display)]
|
||||
elif self.controller.resume_main_flow == Controller.FLOW__ADDRESS_EXPLORER:
|
||||
button_data = [self.ADDRESS_EXPLORER]
|
||||
|
||||
@@ -2069,7 +2061,7 @@ class MultisigWalletDescriptorView(View):
|
||||
self.controller.resume_main_flow = None
|
||||
return Destination(PSBTChangeDetailsView, view_args=dict(change_address_num=0))
|
||||
|
||||
elif button_data[selected_menu_num].startswith(self.VERIFY_ADDR):
|
||||
elif button_data[selected_menu_num].button_label.startswith(_(self.VERIFY_ADDR.button_label)):
|
||||
self.controller.resume_main_flow = None
|
||||
return Destination(SeedAddressVerificationView)
|
||||
|
||||
@@ -2111,12 +2103,7 @@ class SeedSignMessageStartView(View):
|
||||
# Note: addr_format["network"] can be MAINNET or [TESTNET, REGTEST]
|
||||
if self.settings.get_value(SettingsConstants.SETTING__NETWORK) not in addr_format["network"]:
|
||||
from seedsigner.views.view import NetworkMismatchErrorView
|
||||
# TRANSLATOR_NOTE: Inserts mainnet/testnet/regtest and derivation path
|
||||
text = _("Current network setting ({}) doesn't match {}").format(
|
||||
self.settings.get_value_display_name(SettingsConstants.SETTING__NETWORK),
|
||||
self.derivation_path,
|
||||
)
|
||||
self.set_redirect(Destination(NetworkMismatchErrorView, view_args=dict(text=text)))
|
||||
self.set_redirect(Destination(NetworkMismatchErrorView, view_args=dict(derivation_path=self.derivation_path)))
|
||||
|
||||
# cleanup. Note: We could leave this in place so the user can resume the
|
||||
# flow, but for now we avoid complications and keep things simple.
|
||||
@@ -2203,11 +2190,7 @@ class SeedSignMessageConfirmAddressView(View):
|
||||
addr_format["network"] = self.settings.get_value(SettingsConstants.SETTING__NETWORK)
|
||||
else:
|
||||
from seedsigner.views.view import NetworkMismatchErrorView
|
||||
text = _("Current network setting ({}) doesn't match {}").format(
|
||||
self.settings.get_value_display_name(SettingsConstants.SETTING__NETWORK),
|
||||
self.derivation_path,
|
||||
)
|
||||
self.set_redirect(Destination(NetworkMismatchErrorView, view_args=dict(text=text)))
|
||||
self.set_redirect(Destination(NetworkMismatchErrorView, view_args=dict(derivation_path=self.derivation_path)))
|
||||
|
||||
# cleanup. Note: We could leave this in place so the user can resume the
|
||||
# flow, but for now we avoid complications and keep things simple.
|
||||
|
||||
@@ -3,6 +3,7 @@ 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.gui.screens.screen import ButtonOption
|
||||
from seedsigner.models.settings import Settings, SettingsConstants, SettingsDefinition
|
||||
|
||||
from .view import View, Destination, MainMenuView
|
||||
@@ -12,8 +13,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SettingsMenuView(View):
|
||||
IO_TEST = _("I/O test")
|
||||
DONATE = _("Donate")
|
||||
IO_TEST = ButtonOption("I/O test")
|
||||
DONATE = ButtonOption("Donate")
|
||||
|
||||
def __init__(self, visibility: str = SettingsConstants.VISIBILITY__GENERAL, selected_attr: str = None, initial_scroll: int = 0):
|
||||
super().__init__()
|
||||
@@ -28,7 +29,7 @@ class SettingsMenuView(View):
|
||||
settings_entries = SettingsDefinition.get_settings_entries(
|
||||
visibility=self.visibility
|
||||
)
|
||||
button_data=[e.display_name for e in settings_entries]
|
||||
button_data=[ButtonOption(e.display_name) for e in settings_entries]
|
||||
|
||||
selected_button = 0
|
||||
if self.selected_attr:
|
||||
@@ -41,7 +42,7 @@ class SettingsMenuView(View):
|
||||
title = _("Settings")
|
||||
|
||||
# Set up the next nested level of menuing
|
||||
button_data.append((_("Advanced"), None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT))
|
||||
button_data.append(ButtonOption("Advanced", right_icon_name=SeedSignerIconConstants.CHEVRON_RIGHT))
|
||||
next_destination = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__ADVANCED})
|
||||
|
||||
button_data.append(self.IO_TEST)
|
||||
@@ -114,7 +115,7 @@ class SettingsEntryUpdateSelectionView(View):
|
||||
value, display_name = value
|
||||
else:
|
||||
display_name = value
|
||||
button_data.append(display_name)
|
||||
button_data.append(ButtonOption(display_name))
|
||||
|
||||
if (type(initial_value) == list and value in initial_value) or value == initial_value:
|
||||
checked_buttons.append(i)
|
||||
@@ -211,7 +212,6 @@ class SettingsIngestSettingsQRView(View):
|
||||
SettingsQRConfirmationScreen,
|
||||
title=_("Settings QR"),
|
||||
config_name=self.config_name,
|
||||
button_data=[_("Home")],
|
||||
status_message=self.status_message,
|
||||
)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from gettext import gettext as _
|
||||
|
||||
from seedsigner.gui.components import FontAwesomeIconConstants, GUIConstants, SeedSignerIconConstants
|
||||
from seedsigner.gui.screens import RET_CODE__BACK_BUTTON, ButtonListScreen
|
||||
from seedsigner.gui.screens.screen import ButtonOption
|
||||
from seedsigner.helpers import mnemonic_generation
|
||||
from seedsigner.models.seed import Seed
|
||||
from seedsigner.models.settings_definition import SettingsConstants
|
||||
@@ -19,11 +20,11 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ToolsMenuView(View):
|
||||
IMAGE = (_("New seed"), FontAwesomeIconConstants.CAMERA)
|
||||
DICE = (_("New seed"), FontAwesomeIconConstants.DICE)
|
||||
KEYBOARD = (_("Calc 12th/24th word"), FontAwesomeIconConstants.KEYBOARD)
|
||||
ADDRESS_EXPLORER = _("Address Explorer")
|
||||
VERIFY_ADDRESS = _("Verify Address")
|
||||
IMAGE = ButtonOption("New seed", FontAwesomeIconConstants.CAMERA)
|
||||
DICE = ButtonOption("New seed", FontAwesomeIconConstants.DICE)
|
||||
KEYBOARD = ButtonOption("Calc 12th/24th word", FontAwesomeIconConstants.KEYBOARD)
|
||||
ADDRESS_EXPLORER = ButtonOption("Address Explorer")
|
||||
VERIFY_ADDRESS = ButtonOption("Verify Address")
|
||||
|
||||
def run(self):
|
||||
button_data = [self.IMAGE, self.DICE, self.KEYBOARD, self.ADDRESS_EXPLORER, self.VERIFY_ADDRESS]
|
||||
@@ -113,8 +114,8 @@ class ToolsImageEntropyFinalImageView(View):
|
||||
|
||||
|
||||
class ToolsImageEntropyMnemonicLengthView(View):
|
||||
TWELVE_WORDS = _("12 words")
|
||||
TWENTYFOUR_WORDS = _("24 words")
|
||||
TWELVE_WORDS = ButtonOption("12 words", return_data=12)
|
||||
TWENTYFOUR_WORDS = ButtonOption("24 words", return_data=24)
|
||||
|
||||
def run(self):
|
||||
button_data = [self.TWELVE_WORDS, self.TWENTYFOUR_WORDS]
|
||||
@@ -127,10 +128,7 @@ class ToolsImageEntropyMnemonicLengthView(View):
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
if button_data[selected_menu_num] == self.TWELVE_WORDS:
|
||||
mnemonic_length = 12
|
||||
else:
|
||||
mnemonic_length = 24
|
||||
mnemonic_length = button_data[selected_menu_num].return_data
|
||||
|
||||
preview_images = self.controller.image_entropy_preview_frames
|
||||
seed_entropy_image = self.controller.image_entropy_final_image
|
||||
@@ -186,15 +184,19 @@ class ToolsImageEntropyMnemonicLengthView(View):
|
||||
Dice rolls Views
|
||||
****************************************************************************"""
|
||||
class ToolsDiceEntropyMnemonicLengthView(View):
|
||||
# TRANSLATOR_NOTE: Inserts the number of dice rolls needed for a 12-word mnemonic
|
||||
TWELVE = _("12 words ({} rolls)").format(mnemonic_generation.DICE__NUM_ROLLS__12WORD)
|
||||
|
||||
# TRANSLATOR_NOTE: Inserts the number of dice rolls needed for a 24-word mnemonic
|
||||
TWENTY_FOUR = _("24 words ({} rolls)").format(mnemonic_generation.DICE__NUM_ROLLS__24WORD)
|
||||
|
||||
|
||||
def run(self):
|
||||
button_data = [self.TWELVE, self.TWENTY_FOUR]
|
||||
# Since we're dynamically building the ButtonOption button_labels here, it's too
|
||||
# awkward to use the usual class-level attr approach.
|
||||
|
||||
# TRANSLATOR_NOTE: Inserts the number of dice rolls needed for a 12-word mnemonic
|
||||
twelve = _("12 words ({} rolls)").format(mnemonic_generation.DICE__NUM_ROLLS__12WORD)
|
||||
TWELVE = ButtonOption(twelve, return_data=mnemonic_generation.DICE__NUM_ROLLS__12WORD)
|
||||
|
||||
# TRANSLATOR_NOTE: Inserts the number of dice rolls needed for a 24-word mnemonic
|
||||
twenty_four = _("24 words ({} rolls)").format(mnemonic_generation.DICE__NUM_ROLLS__24WORD)
|
||||
TWENTY_FOUR = ButtonOption(twenty_four, return_data=mnemonic_generation.DICE__NUM_ROLLS__24WORD)
|
||||
|
||||
button_data = [TWELVE, TWENTY_FOUR]
|
||||
selected_menu_num = ButtonListScreen(
|
||||
title=_("Mnemonic Length"),
|
||||
is_bottom_list=True,
|
||||
@@ -205,10 +207,10 @@ class ToolsDiceEntropyMnemonicLengthView(View):
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
elif button_data[selected_menu_num] == self.TWELVE:
|
||||
elif button_data[selected_menu_num] == TWELVE:
|
||||
return Destination(ToolsDiceEntropyEntryView, view_args=dict(total_rolls=mnemonic_generation.DICE__NUM_ROLLS__12WORD))
|
||||
|
||||
elif button_data[selected_menu_num] == self.TWENTY_FOUR:
|
||||
elif button_data[selected_menu_num] == TWENTY_FOUR:
|
||||
return Destination(ToolsDiceEntropyEntryView, view_args=dict(total_rolls=mnemonic_generation.DICE__NUM_ROLLS__24WORD))
|
||||
|
||||
|
||||
@@ -243,8 +245,8 @@ class ToolsDiceEntropyEntryView(View):
|
||||
Calc final word Views
|
||||
****************************************************************************"""
|
||||
class ToolsCalcFinalWordNumWordsView(View):
|
||||
TWELVE = _("12 words")
|
||||
TWENTY_FOUR = _("24 words")
|
||||
TWELVE = ButtonOption("12 words", return_data=12)
|
||||
TWENTY_FOUR = ButtonOption("24 words", return_data=24)
|
||||
|
||||
def run(self):
|
||||
button_data = [self.TWELVE, self.TWENTY_FOUR]
|
||||
@@ -260,29 +262,21 @@ class ToolsCalcFinalWordNumWordsView(View):
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
elif button_data[selected_menu_num] == self.TWELVE:
|
||||
self.controller.storage.init_pending_mnemonic(12)
|
||||
self.controller.storage.init_pending_mnemonic(button_data[selected_menu_num].return_data)
|
||||
|
||||
# return Destination(SeedMnemonicEntryView, view_args=dict(is_calc_final_word=True))
|
||||
return Destination(SeedMnemonicEntryView, view_args=dict(is_calc_final_word=True))
|
||||
|
||||
elif button_data[selected_menu_num] == self.TWENTY_FOUR:
|
||||
self.controller.storage.init_pending_mnemonic(24)
|
||||
|
||||
# return Destination(SeedMnemonicEntryView, view_args=dict(is_calc_final_word=True))
|
||||
return Destination(SeedMnemonicEntryView, view_args=dict(is_calc_final_word=True))
|
||||
return Destination(SeedMnemonicEntryView, view_args=dict(is_calc_final_word=True))
|
||||
|
||||
|
||||
|
||||
class ToolsCalcFinalWordFinalizePromptView(View):
|
||||
# TRANSLATOR_NOTE: Label to gather entropy through coin tosses
|
||||
COIN_FLIPS = _("Coin flip entropy")
|
||||
COIN_FLIPS = ButtonOption("Coin flip entropy")
|
||||
|
||||
# TRANSLATOR_NOTE: Label to gather entropy through user specified BIP-39 word
|
||||
SELECT_WORD = _("Word selection entropy")
|
||||
SELECT_WORD = ButtonOption("Word selection entropy")
|
||||
|
||||
# TRANSLATOR_NOTE: Label to allow user to default entropy as all-zeros
|
||||
ZEROS = _("Finalize with zeros")
|
||||
ZEROS = ButtonOption("Finalize with zeros")
|
||||
|
||||
def run(self):
|
||||
from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordFinalizePromptScreen
|
||||
@@ -343,7 +337,7 @@ class ToolsCalcFinalWordCoinFlipsView(View):
|
||||
|
||||
|
||||
class ToolsCalcFinalWordShowFinalWordView(View):
|
||||
NEXT = _("Next")
|
||||
NEXT = ButtonOption("Next")
|
||||
|
||||
def __init__(self, coin_flips: str = None):
|
||||
super().__init__()
|
||||
@@ -399,10 +393,13 @@ class ToolsCalcFinalWordShowFinalWordView(View):
|
||||
def run(self):
|
||||
from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordScreen
|
||||
button_data = [self.NEXT]
|
||||
|
||||
# TRANSLATOR_NOTE: label to calculate the last word of a BIP-39 mnemonic seed phrase
|
||||
title = _("Final Word Calc")
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ToolsCalcFinalWordScreen,
|
||||
# TRANSLATOR_NOTE: label to calculate the last word of a BIP-39 mnemonic seed phrase
|
||||
title=_("Final Word Calc"),
|
||||
title=title,
|
||||
button_data=button_data,
|
||||
selected_final_word=self.selected_final_word,
|
||||
selected_final_bits=self.selected_final_bits,
|
||||
@@ -419,8 +416,8 @@ class ToolsCalcFinalWordShowFinalWordView(View):
|
||||
|
||||
|
||||
class ToolsCalcFinalWordDoneView(View):
|
||||
LOAD = _("Load seed")
|
||||
DISCARD = (_("Discard"), None, None, "red")
|
||||
LOAD = ButtonOption("Load seed")
|
||||
DISCARD = ButtonOption("Discard", button_label_color="red")
|
||||
|
||||
def run(self):
|
||||
from seedsigner.gui.screens.tools_screens import ToolsCalcFinalWordDoneScreen
|
||||
@@ -454,11 +451,11 @@ class ToolsCalcFinalWordDoneView(View):
|
||||
Address Explorer Views
|
||||
****************************************************************************"""
|
||||
class ToolsAddressExplorerSelectSourceView(View):
|
||||
SCAN_SEED = (_("Scan a seed"), SeedSignerIconConstants.QRCODE)
|
||||
SCAN_DESCRIPTOR = (_("Scan wallet descriptor"), SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = (_("Enter 12-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = (_("Enter 24-word seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_ELECTRUM = (_("Enter Electrum seed"), FontAwesomeIconConstants.KEYBOARD)
|
||||
SCAN_SEED = ButtonOption("Scan a seed", SeedSignerIconConstants.QRCODE)
|
||||
SCAN_DESCRIPTOR = ButtonOption("Scan wallet descriptor", SeedSignerIconConstants.QRCODE)
|
||||
TYPE_12WORD = ButtonOption("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD, return_data=12)
|
||||
TYPE_24WORD = ButtonOption("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD, return_data=24)
|
||||
TYPE_ELECTRUM = ButtonOption("Enter Electrum seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
|
||||
def run(self):
|
||||
from seedsigner.controller import Controller
|
||||
@@ -467,11 +464,11 @@ class ToolsAddressExplorerSelectSourceView(View):
|
||||
button_data = []
|
||||
for seed in seeds:
|
||||
button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK))
|
||||
button_data.append((button_str, SeedSignerIconConstants.FINGERPRINT))
|
||||
button_data.append(ButtonOption(button_str, SeedSignerIconConstants.FINGERPRINT))
|
||||
button_data = button_data + [self.SCAN_SEED, self.SCAN_DESCRIPTOR, self.TYPE_12WORD, self.TYPE_24WORD]
|
||||
if self.settings.get_value(SettingsConstants.SETTING__ELECTRUM_SEEDS) == SettingsConstants.OPTION__ENABLED:
|
||||
button_data.append(self.TYPE_ELECTRUM)
|
||||
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
title=_("Address Explorer"),
|
||||
@@ -508,10 +505,7 @@ class ToolsAddressExplorerSelectSourceView(View):
|
||||
|
||||
elif button_data[selected_menu_num] in [self.TYPE_12WORD, self.TYPE_24WORD]:
|
||||
from seedsigner.views.seed_views import SeedMnemonicEntryView
|
||||
if button_data[selected_menu_num] == self.TYPE_12WORD:
|
||||
self.controller.storage.init_pending_mnemonic(num_words=12)
|
||||
else:
|
||||
self.controller.storage.init_pending_mnemonic(num_words=24)
|
||||
self.controller.storage.init_pending_mnemonic(num_words=button_data[selected_menu_num].return_data)
|
||||
return Destination(SeedMnemonicEntryView)
|
||||
|
||||
elif button_data[selected_menu_num] == self.TYPE_ELECTRUM:
|
||||
@@ -522,10 +516,10 @@ class ToolsAddressExplorerSelectSourceView(View):
|
||||
|
||||
class ToolsAddressExplorerAddressTypeView(View):
|
||||
# TRANSLATOR_NOTE: label for addresses where others send us incoming payments
|
||||
RECEIVE = _("Receive Addresses")
|
||||
RECEIVE = ButtonOption("Receive Addresses")
|
||||
|
||||
# TRANSLATOR_NOTE: label for addresses that collect the change from our own outgoing payments
|
||||
CHANGE = _("Change Addresses")
|
||||
CHANGE = ButtonOption("Change Addresses")
|
||||
|
||||
|
||||
def __init__(self, seed_num: int = None, script_type: str = None, custom_derivation: str = None):
|
||||
@@ -689,10 +683,11 @@ class ToolsAddressExplorerAddressListView(View):
|
||||
end_digits = -5
|
||||
else:
|
||||
end_digits = -4
|
||||
button_data.append(f"{cur_index}:{address[:8]}...{address[end_digits:]}")
|
||||
button_data.append(ButtonOption(f"{cur_index}:{address[:8]}...{address[end_digits:]}"))
|
||||
|
||||
# TRANSLATOR_NOTE: Insert the number of addrs displayed per screen (e.g. "Next 10")
|
||||
button_data.append((_("Next {}").format(addrs_per_screen), None, None, None, SeedSignerIconConstants.CHEVRON_RIGHT))
|
||||
button_label = _("Next {}").format(addrs_per_screen)
|
||||
button_data.append(ButtonOption(button_label, right_icon_name=SeedSignerIconConstants.CHEVRON_RIGHT))
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from gettext import gettext as _
|
||||
from typing import Type
|
||||
|
||||
from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerIconConstants
|
||||
from seedsigner.helpers.l10n import mark_for_translation as _mft
|
||||
from seedsigner.gui.components import SeedSignerIconConstants
|
||||
from seedsigner.gui.screens import RET_CODE__POWER_BUTTON, RET_CODE__BACK_BUTTON
|
||||
from seedsigner.gui.screens.screen import BaseScreen, DireWarningScreen, LargeButtonScreen, PowerOffScreen, PowerOffNotRequiredScreen, ResetScreen, WarningScreen
|
||||
from seedsigner.gui.screens.screen import BaseScreen, ButtonOption, DireWarningScreen, LargeButtonScreen, PowerOffScreen, PowerOffNotRequiredScreen, ResetScreen, WarningScreen
|
||||
from seedsigner.models.settings import Settings, SettingsConstants
|
||||
from seedsigner.models.settings_definition import SettingsDefinition
|
||||
from seedsigner.models.threads import BaseThread
|
||||
@@ -18,6 +19,7 @@ class BackStackView:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Views contain the biz logic to handle discrete tasks, exactly analogous to a Flask
|
||||
request/response function or a Django View. Each page/screen displayed to the user
|
||||
@@ -182,14 +184,13 @@ class Destination:
|
||||
#
|
||||
#########################################################################################
|
||||
class MainMenuView(View):
|
||||
SCAN = (_("Scan"), SeedSignerIconConstants.SCAN)
|
||||
SEEDS = (_("Seeds"), SeedSignerIconConstants.SEEDS)
|
||||
TOOLS = (_("Tools"), SeedSignerIconConstants.TOOLS)
|
||||
SETTINGS = (_("Settings"), SeedSignerIconConstants.SETTINGS)
|
||||
SCAN = ButtonOption("Scan", SeedSignerIconConstants.SCAN)
|
||||
SEEDS = ButtonOption("Seeds", SeedSignerIconConstants.SEEDS)
|
||||
TOOLS = ButtonOption("Tools", SeedSignerIconConstants.TOOLS)
|
||||
SETTINGS = ButtonOption("Settings", SeedSignerIconConstants.SETTINGS)
|
||||
|
||||
def run(self):
|
||||
from seedsigner.gui.screens.screen import MainMenuScreen
|
||||
|
||||
button_data = [self.SCAN, self.SEEDS, self.TOOLS, self.SETTINGS]
|
||||
selected_menu_num = self.run_screen(
|
||||
MainMenuScreen,
|
||||
@@ -219,8 +220,8 @@ class MainMenuView(View):
|
||||
|
||||
|
||||
class PowerOptionsView(View):
|
||||
RESET = (_("Restart"), SeedSignerIconConstants.RESTART)
|
||||
POWER_OFF = (_("Power Off"), SeedSignerIconConstants.POWER)
|
||||
RESET = ButtonOption("Restart", SeedSignerIconConstants.RESTART)
|
||||
POWER_OFF = ButtonOption("Power Off", SeedSignerIconConstants.POWER)
|
||||
|
||||
def run(self):
|
||||
button_data = [self.RESET, self.POWER_OFF]
|
||||
@@ -293,12 +294,7 @@ class NotYetImplementedView(View):
|
||||
"""
|
||||
Temporary View to use during dev.
|
||||
"""
|
||||
text: str = None
|
||||
|
||||
def __post_init__(self):
|
||||
if not self.text:
|
||||
self.text = _("This is still on our to-do list!")
|
||||
return super().__post_init__()
|
||||
text: str = _mft("This is still on our to-do list!")
|
||||
|
||||
|
||||
def run(self):
|
||||
@@ -307,7 +303,7 @@ class NotYetImplementedView(View):
|
||||
title=_("Work In Progress"),
|
||||
status_headline=_("Not Yet Implemented"),
|
||||
text=self.text,
|
||||
button_data=[_("Back to Main Menu")],
|
||||
button_data=[ButtonOption("Back to Main Menu")],
|
||||
)
|
||||
|
||||
return Destination(MainMenuView)
|
||||
@@ -316,13 +312,12 @@ class NotYetImplementedView(View):
|
||||
|
||||
@dataclass
|
||||
class ErrorView(View):
|
||||
title: str = _("Error")
|
||||
title: str = _mft("Error")
|
||||
show_back_button: bool = True
|
||||
status_headline: str = None
|
||||
text: str = None
|
||||
button_text: str = None
|
||||
next_destination: Destination = field(default_factory=lambda: Destination(MainMenuView, clear_history=True))
|
||||
|
||||
next_destination: Destination = None
|
||||
|
||||
def run(self):
|
||||
self.run_screen(
|
||||
@@ -330,33 +325,30 @@ class ErrorView(View):
|
||||
title=self.title,
|
||||
status_headline=self.status_headline,
|
||||
text=self.text,
|
||||
button_data=[self.button_text],
|
||||
button_data=[ButtonOption(self.button_text)],
|
||||
show_back_button=self.show_back_button,
|
||||
)
|
||||
|
||||
return self.next_destination
|
||||
return self.next_destination if self.next_destination else Destination(MainMenuView, clear_history=True)
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class NetworkMismatchErrorView(ErrorView):
|
||||
title: str = _("Network Mismatch")
|
||||
show_back_button: bool = False
|
||||
button_text: str = _("Change Setting")
|
||||
next_destination: Destination = None
|
||||
|
||||
derivation_path: str = None
|
||||
|
||||
def __post_init__(self):
|
||||
from seedsigner.views.settings_views import SettingsEntryUpdateSelectionView
|
||||
self.title: str = _("Network Mismatch")
|
||||
self.show_back_button: bool = False
|
||||
self.button_text: str = _("Change Setting")
|
||||
self.next_destination = Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=SettingsConstants.SETTING__NETWORK), clear_history=True)
|
||||
super().__post_init__()
|
||||
if not self.text:
|
||||
# TRANSLATOR_NOTE: Inserts mainnet/testnet/regtest
|
||||
self.text = _("Current network setting ({}) doesn't match current action.").format(
|
||||
self.settings.get_value_display_name(SettingsConstants.SETTING__NETWORK),
|
||||
)
|
||||
|
||||
if not self.next_destination:
|
||||
from seedsigner.views.settings_views import SettingsEntryUpdateSelectionView
|
||||
self.next_destination = Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=SettingsConstants.SETTING__NETWORK), clear_history=True)
|
||||
# TRANSLATOR_NOTE: Inserts mainnet/testnet/regtest and derivation path
|
||||
self.text = _("Current network setting ({}) doesn't match {}.").format(
|
||||
self.settings.get_value_display_name(SettingsConstants.SETTING__NETWORK),
|
||||
self.derivation_path,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -380,14 +372,12 @@ class UnhandledExceptionView(View):
|
||||
|
||||
@dataclass
|
||||
class OptionDisabledView(View):
|
||||
UPDATE_SETTING = "Update Setting"
|
||||
DONE = "Done"
|
||||
UPDATE_SETTING = ButtonOption("Update Setting")
|
||||
DONE = ButtonOption("Done")
|
||||
settings_attr: str
|
||||
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
self.UPDATE_SETTING = _("Update Setting")
|
||||
self.DONE = _("Done")
|
||||
self.settings_entry = SettingsDefinition.get_settings_entry(self.settings_attr)
|
||||
|
||||
# TRANSLATOR_NOTE: Inserts the name of a settings option (e.g. "Persistent Settings" is currently...)
|
||||
@@ -413,26 +403,3 @@ class OptionDisabledView(View):
|
||||
return Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=self.settings_attr), clear_history=True)
|
||||
else:
|
||||
return Destination(MainMenuView, clear_history=True)
|
||||
|
||||
|
||||
|
||||
class RemoveMicroSDWarningView(View):
|
||||
"""
|
||||
Warning to remove the microsd
|
||||
"""
|
||||
def __init__(self, next_view: View):
|
||||
super().__init__()
|
||||
self.next_view = next_view
|
||||
|
||||
def run(self):
|
||||
self.run_screen(
|
||||
WarningScreen,
|
||||
title=_("Security Tip"),
|
||||
status_icon_name=FontAwesomeIconConstants.SDCARD,
|
||||
status_headline="",
|
||||
text=_("For maximum security,\nremove the MicroSD card\nbefore continuing."),
|
||||
show_back_button=False,
|
||||
button_data=[_("Continue")],
|
||||
)
|
||||
|
||||
return Destination(self.next_view, clear_history=True)
|
||||
|
||||
@@ -295,7 +295,7 @@ def test_generate_screenshots(target_locale):
|
||||
"Misc Error Views": [
|
||||
NotYetImplementedView,
|
||||
(UnhandledExceptionView, dict(error=["IndexError", "line 1, in some_buggy_code.py", "list index out of range"])),
|
||||
NetworkMismatchErrorView,
|
||||
(NetworkMismatchErrorView, dict(derivation_path="m/84'/1'/0'")),
|
||||
(OptionDisabledView, dict(settings_attr=SettingsConstants.SETTING__MESSAGE_SIGNING)),
|
||||
(ErrorView, dict(
|
||||
title="Error",
|
||||
|
||||
@@ -115,7 +115,7 @@ class TestPSBTFlows(FlowTest):
|
||||
FlowStep(psbt_views.PSBTSigningErrorView, button_data_selection=psbt_views.PSBTSigningErrorView.SELECT_DIFF_SEED),
|
||||
FlowStep(psbt_views.PSBTSelectSeedView, button_data_selection=psbt_views.PSBTSelectSeedView.SCAN_SEED),
|
||||
FlowStep(scan_views.ScanSeedQRView, before_run=load_seed_into_decoder),
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=SettingsConstants.LABEL__BIP39_PASSPHRASE),
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=seed_views.SeedFinalizeView.PASSPHRASE),
|
||||
FlowStep(seed_views.SeedAddPassphraseView, screen_return_value=dict(passphrase="abc")),
|
||||
FlowStep(seed_views.SeedReviewPassphraseView, button_data_selection=seed_views.SeedReviewPassphraseView.DONE),
|
||||
FlowStep(seed_views.SeedOptionsView, is_redirect=True),
|
||||
|
||||
+23
-12
@@ -5,7 +5,7 @@ import pytest
|
||||
from base import BaseTest, FlowTest, FlowStep
|
||||
from base import FlowTestInvalidButtonDataSelectionException
|
||||
|
||||
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON
|
||||
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON, ButtonOption
|
||||
from seedsigner.models.settings import Settings, SettingsConstants
|
||||
from seedsigner.models.seed import ElectrumSeed, Seed
|
||||
from seedsigner.views.view import ErrorView, MainMenuView, OptionDisabledView, View, NetworkMismatchErrorView
|
||||
@@ -40,10 +40,10 @@ class TestSeedFlows(FlowTest):
|
||||
self.run_sequence([
|
||||
FlowStep(MainMenuView, button_data_selection=MainMenuView.SCAN),
|
||||
FlowStep(scan_views.ScanView, before_run=load_seed_into_decoder), # simulate read SeedQR; ret val is ignored
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=SettingsConstants.LABEL__BIP39_PASSPHRASE),
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=seed_views.SeedFinalizeView.PASSPHRASE),
|
||||
FlowStep(seed_views.SeedAddPassphraseView, screen_return_value=dict(passphrase="muhpassphrase", is_back_button=True)),
|
||||
FlowStep(seed_views.SeedAddPassphraseExitDialogView, button_data_selection=seed_views.SeedAddPassphraseExitDialogView.DISCARD),
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=SettingsConstants.LABEL__BIP39_PASSPHRASE),
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=seed_views.SeedFinalizeView.PASSPHRASE),
|
||||
FlowStep(seed_views.SeedAddPassphraseView, screen_return_value=dict(passphrase="muhpassphrase", is_back_button=True)),
|
||||
FlowStep(seed_views.SeedAddPassphraseExitDialogView, button_data_selection=seed_views.SeedAddPassphraseExitDialogView.EDIT),
|
||||
FlowStep(seed_views.SeedAddPassphraseView, screen_return_value=dict(passphrase="muhpassphrase")),
|
||||
@@ -183,15 +183,18 @@ class TestSeedFlows(FlowTest):
|
||||
"""
|
||||
Selecting "Export XPUB" from the SeedOptionsView should enter the Export XPUB flow and end at the MainMenuView
|
||||
"""
|
||||
|
||||
def flowtest_standard_xpub(sig_tuple, script_tuple, coord_tuple):
|
||||
if sig_tuple[0] == SettingsConstants.SINGLE_SIG:
|
||||
sig_selection = seed_views.SeedExportXpubSigTypeView.SINGLE_SIG
|
||||
else:
|
||||
sig_selection = seed_views.SeedExportXpubSigTypeView.MULTISIG
|
||||
self.run_sequence(
|
||||
initial_destination_view_args=dict(seed_num=0),
|
||||
sequence=[
|
||||
FlowStep(seed_views.SeedOptionsView, button_data_selection=seed_views.SeedOptionsView.EXPORT_XPUB),
|
||||
FlowStep(seed_views.SeedExportXpubSigTypeView, button_data_selection=sig_tuple[1]),
|
||||
FlowStep(seed_views.SeedExportXpubScriptTypeView, button_data_selection=script_tuple[1]),
|
||||
FlowStep(seed_views.SeedExportXpubCoordinatorView, button_data_selection=coord_tuple[1]),
|
||||
FlowStep(seed_views.SeedExportXpubSigTypeView, button_data_selection=sig_selection),
|
||||
FlowStep(seed_views.SeedExportXpubScriptTypeView, button_data_selection=ButtonOption(script_tuple[1], return_data=script_tuple[0])),
|
||||
FlowStep(seed_views.SeedExportXpubCoordinatorView, button_data_selection=ButtonOption(coord_tuple[1], return_data=coord_tuple[0])),
|
||||
FlowStep(seed_views.SeedExportXpubWarningView, screen_return_value=0),
|
||||
FlowStep(seed_views.SeedExportXpubDetailsView, screen_return_value=0),
|
||||
FlowStep(seed_views.SeedExportXpubQRDisplayView, screen_return_value=0),
|
||||
@@ -303,10 +306,18 @@ class TestSeedFlows(FlowTest):
|
||||
SettingsConstants.CUSTOM_DERIVATION
|
||||
])
|
||||
|
||||
# get display names to access button choices in the views (ugh: hardcoding, is there a better way?)
|
||||
sig_type = self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__SIG_TYPES)[0] # single sig
|
||||
script_type = self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__SCRIPT_TYPES)[2] # custom derivation
|
||||
coordinator = self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__COORDINATORS)[3] # specter
|
||||
# Ensure that all coordinators are enabled
|
||||
self.settings.set_value(SettingsConstants.SETTING__COORDINATORS, [x for x, y in SettingsConstants.ALL_COORDINATORS])
|
||||
|
||||
# Set up button_data selections
|
||||
sig_type = seed_views.SeedExportXpubSigTypeView.SINGLE_SIG
|
||||
|
||||
custom_derivation = SettingsConstants.CUSTOM_DERIVATION
|
||||
script_type = ButtonOption(self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__SCRIPT_TYPES)[2], return_data=custom_derivation)
|
||||
|
||||
specter = SettingsConstants.COORDINATOR__SPECTER_DESKTOP
|
||||
assert SettingsConstants.ALL_COORDINATORS[3][0] == specter
|
||||
coordinator = ButtonOption(self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__COORDINATORS)[3], return_data=specter)
|
||||
|
||||
self.run_sequence(
|
||||
initial_destination_view_args=dict(seed_num=0),
|
||||
@@ -377,7 +388,7 @@ class TestSeedFlows(FlowTest):
|
||||
|
||||
# Skips past the script type options via redirect
|
||||
FlowStep(seed_views.SeedExportXpubScriptTypeView, is_redirect=True),
|
||||
FlowStep(seed_views.SeedExportXpubCoordinatorView, button_data_selection=self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__COORDINATORS)[0]),
|
||||
FlowStep(seed_views.SeedExportXpubCoordinatorView, button_data_selection=ButtonOption(self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__COORDINATORS)[0], return_data=SettingsConstants.ALL_COORDINATORS[0][0])),
|
||||
FlowStep(seed_views.SeedExportXpubWarningView, screen_return_value=0),
|
||||
FlowStep(seed_views.SeedExportXpubDetailsView, screen_return_value=0),
|
||||
FlowStep(seed_views.SeedExportXpubQRDisplayView, screen_return_value=0),
|
||||
|
||||
@@ -8,7 +8,7 @@ from base import FlowTest, FlowStep
|
||||
|
||||
from seedsigner.models.settings import Settings
|
||||
from seedsigner.models.settings_definition import SettingsDefinition, SettingsConstants
|
||||
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON
|
||||
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON, ButtonOption
|
||||
from seedsigner.hardware.microsd import MicroSD
|
||||
from seedsigner.views.view import MainMenuView
|
||||
from seedsigner.views import scan_views, settings_views
|
||||
@@ -26,8 +26,8 @@ class TestSettingsFlows(FlowTest):
|
||||
|
||||
self.run_sequence([
|
||||
FlowStep(MainMenuView, button_data_selection=MainMenuView.SETTINGS),
|
||||
FlowStep(settings_views.SettingsMenuView, button_data_selection=settings_entry.display_name),
|
||||
FlowStep(settings_views.SettingsEntryUpdateSelectionView, button_data_selection=settings_entry.get_selection_option_display_name_by_value(SettingsConstants.OPTION__ENABLED)),
|
||||
FlowStep(settings_views.SettingsMenuView, button_data_selection=ButtonOption(settings_entry.display_name)),
|
||||
FlowStep(settings_views.SettingsEntryUpdateSelectionView, button_data_selection=ButtonOption(settings_entry.get_selection_option_display_name_by_value(SettingsConstants.OPTION__ENABLED))),
|
||||
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=RET_CODE__BACK_BUTTON),
|
||||
FlowStep(settings_views.SettingsMenuView),
|
||||
])
|
||||
@@ -43,7 +43,7 @@ class TestSettingsFlows(FlowTest):
|
||||
|
||||
self.run_sequence([
|
||||
FlowStep(MainMenuView, button_data_selection=MainMenuView.SETTINGS),
|
||||
FlowStep(settings_views.SettingsMenuView, button_data_selection=settings_entry.display_name),
|
||||
FlowStep(settings_views.SettingsMenuView, button_data_selection=ButtonOption(settings_entry.display_name)),
|
||||
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=0), # select/deselect first option
|
||||
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # select/deselect second option
|
||||
FlowStep(settings_views.SettingsEntryUpdateSelectionView, screen_return_value=1), # select/deselect second option
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from base import FlowTest, FlowStep
|
||||
|
||||
from seedsigner.controller import Controller
|
||||
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON
|
||||
from seedsigner.gui.screens.screen import RET_CODE__BACK_BUTTON, ButtonOption
|
||||
from seedsigner.models.seed import Seed
|
||||
from seedsigner.models.settings_definition import SettingsConstants, SettingsDefinition
|
||||
from seedsigner.views.view import ErrorView, MainMenuView
|
||||
@@ -25,7 +25,7 @@ class TestToolsFlows(FlowTest):
|
||||
FlowStep(MainMenuView, button_data_selection=MainMenuView.TOOLS),
|
||||
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.ADDRESS_EXPLORER),
|
||||
FlowStep(tools_views.ToolsAddressExplorerSelectSourceView, screen_return_value=0), # ret 1st onboard seed
|
||||
FlowStep(seed_views.SeedExportXpubScriptTypeView, button_data_selection=SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__SCRIPT_TYPES).get_selection_option_display_name_by_value(SettingsConstants.NATIVE_SEGWIT)),
|
||||
FlowStep(seed_views.SeedExportXpubScriptTypeView, button_data_selection=ButtonOption(SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__SCRIPT_TYPES).get_selection_option_display_name_by_value(SettingsConstants.NATIVE_SEGWIT), return_data=SettingsConstants.NATIVE_SEGWIT)),
|
||||
FlowStep(tools_views.ToolsAddressExplorerAddressTypeView, button_data_selection=tools_views.ToolsAddressExplorerAddressTypeView.RECEIVE),
|
||||
FlowStep(tools_views.ToolsAddressExplorerAddressListView, screen_return_value=10), # ret NEXT page of addrs
|
||||
FlowStep(tools_views.ToolsAddressExplorerAddressListView, screen_return_value=4), # ret a specific addr from the list
|
||||
@@ -62,7 +62,7 @@ class TestToolsFlows(FlowTest):
|
||||
# Finalize the new seed w/passphrase
|
||||
self.run_sequence(
|
||||
sequence=[
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=SettingsConstants.LABEL__BIP39_PASSPHRASE),
|
||||
FlowStep(seed_views.SeedFinalizeView, button_data_selection=seed_views.SeedFinalizeView.PASSPHRASE),
|
||||
FlowStep(seed_views.SeedAddPassphraseView, screen_return_value=dict(passphrase="mypassphrase")),
|
||||
FlowStep(seed_views.SeedReviewPassphraseView, button_data_selection=seed_views.SeedReviewPassphraseView.DONE),
|
||||
FlowStep(seed_views.SeedOptionsView, is_redirect=True),
|
||||
|
||||
Reference in New Issue
Block a user