From 477d44f2a021d10b8cbd2d214dc1116bf0620000 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Fri, 1 Apr 2022 07:38:59 -0500 Subject: [PATCH] Test suite fixes; DonateView * Updated custom SeedSigner icon font pack * Removing debugging print statements * Default button handling for BaseTopNavScreen --- src/seedsigner/controller.py | 11 +- src/seedsigner/gui/components.py | 39 +++---- src/seedsigner/gui/renderer.py | 6 +- src/seedsigner/gui/screens/psbt_screens.py | 6 +- src/seedsigner/gui/screens/screen.py | 48 ++++++-- .../gui/screens/settings_screens.py | 23 +++- src/seedsigner/models/decode_qr.py | 6 +- src/seedsigner/models/psbt_parser.py | 4 +- src/seedsigner/models/settings_definition.py | 2 - .../resources/fonts/seedsigner-glyphs.otf | Bin 16092 -> 11808 bytes src/seedsigner/views/psbt_views.py | 4 +- src/seedsigner/views/seed_views.py | 14 +-- src/seedsigner/views/settings_views.py | 25 +++- src/seedsigner/views/tools_views.py | 9 +- tests/test_controller.py | 59 ++-------- tests/test_decodepsbtqr.py | 109 ++++-------------- tests/test_encodepsbtqr.py | 38 +++--- tests/test_seed.py | 9 +- tests/test_seedqr.py | 5 +- 19 files changed, 179 insertions(+), 238 deletions(-) diff --git a/src/seedsigner/controller.py b/src/seedsigner/controller.py index 5431f62c..8c91e9d4 100644 --- a/src/seedsigner/controller.py +++ b/src/seedsigner/controller.py @@ -49,7 +49,7 @@ class Controller(Singleton): rather than at the top in order avoid circular imports. """ - VERSION = "0.5.0 Pre-Release 3" + VERSION = "0.5.0" # Declare class member vars with type hints to enable richer IDE support throughout # the code. @@ -185,15 +185,6 @@ class Controller(Singleton): opening_splash = OpeningSplashView() opening_splash.start() - # TODO: Remove for v0.5.0 production release - WarningScreen( - title="Warning", - status_headline="Pre-Release Code", - text="Do not use this with real funds or to create new secure keys!", - show_back_button=False, - ).display() - - """ Class references can be stored as variables in python! This loop receives a View class to execute and stores it in the `View_cls` diff --git a/src/seedsigner/gui/components.py b/src/seedsigner/gui/components.py index ce723dce..18bff593 100644 --- a/src/seedsigner/gui/components.py +++ b/src/seedsigner/gui/components.py @@ -1,5 +1,4 @@ import math -from operator import is_ import os import pathlib @@ -33,7 +32,7 @@ class GUIConstants: ICON_FONT_SIZE = 22 ICON_INLINE_FONT_SIZE = 24 ICON_LARGE_BUTTON_SIZE = 36 - ICON_PRIMARY_SCREEN_SIZE = 44 + ICON_PRIMARY_SCREEN_SIZE = 60 TOP_NAV_TITLE_FONT_NAME = "OpenSans-SemiBold" TOP_NAV_TITLE_FONT_SIZE = 20 @@ -109,18 +108,19 @@ class FontAwesomeIconConstants: class SeedSignerCustomIconConstants: LARGE_CHEVRON_LEFT = "\ue900" SMALL_CHEVRON_RIGHT = "\ue901" - PAGE_DOWN = "\ue902" PAGE_UP = "\ue903" - CIRCLE_X = "\ue904" - CIRCLE_EXCLAMATION = "\ue905" - CIRCLE_CHECK = "\ue906" - FINGERPRINT = "\ue907" - PATH = "\ue908" - BITCOIN_LOGO = "\ue909" - BITCOIN_LOGO_2 = "\ue90a" + PAGE_DOWN = "\ue902" + PLUS = "\ue904" + CIRCLE_CHECK = "\ue907" + CIRCLE_EXCLAMATION = "\ue908" + CIRCLE_X = "\ue909" + FINGERPRINT = "\ue90a" + PATH = "\ue90b" + BITCOIN_LOGO_STRAIGHT = "\ue90c" + BITCOIN_LOGO_TILTED = "\ue90d" MIN_VALUE = LARGE_CHEVRON_LEFT - MAX_VALUE = BITCOIN_LOGO_2 + MAX_VALUE = BITCOIN_LOGO_TILTED @@ -419,7 +419,7 @@ class TextArea(BaseComponent): class Icon(BaseComponent): screen_x: int = 0 screen_y: int = 0 - icon_name: str = SeedSignerCustomIconConstants.BITCOIN_LOGO + icon_name: str = SeedSignerCustomIconConstants.BITCOIN_LOGO_TILTED icon_size: int = GUIConstants.ICON_FONT_SIZE icon_color: str = GUIConstants.BODY_FONT_COLOR @@ -438,11 +438,11 @@ class Icon(BaseComponent): def render(self): self.image_draw.text( - (self.screen_x, self.screen_y), + (self.screen_x, self.screen_y + self.height), text=self.icon_name, font=self.icon_font, fill=self.icon_color, - anchor="lt", # left, top anchor to avoid "ascender" gap space + anchor="ls", ) @@ -539,7 +539,8 @@ class IconTextLine(BaseComponent): if self.icon_name: icon_y = self.screen_y + int((self.height - self.icon.height)/2) self.icon.screen_y = icon_y - self.height = self.icon.height + + self.height = max(self.icon.height, self.height) if self.is_text_centered: if self.icon_name: @@ -762,8 +763,6 @@ class BtcAmount(BaseComponent): denomination = Settings.get_instance().get_value(SettingsConstants.SETTING__BTC_DENOMINATION) network = Settings.get_instance().get_value(SettingsConstants.SETTING__NETWORK) - print(self.total_sats) - btc_unit = "tBtc" sats_unit = "tSats" if network == SettingsConstants.MAINNET: @@ -789,7 +788,7 @@ class BtcAmount(BaseComponent): btc_icon = Icon( image_draw=draw, canvas=self.paste_image, - icon_name=SeedSignerCustomIconConstants.BITCOIN_LOGO, + icon_name=SeedSignerCustomIconConstants.BITCOIN_LOGO_TILTED, icon_color=btc_color, icon_size=self.icon_size, screen_x=0, @@ -877,7 +876,7 @@ class BtcAmount(BaseComponent): btc_icon = Icon( image_draw=draw, canvas=self.paste_image, - icon_name=SeedSignerCustomIconConstants.BITCOIN_LOGO, + icon_name=SeedSignerCustomIconConstants.BITCOIN_LOGO_TILTED, icon_color=btc_color, icon_size=self.icon_size, screen_x=0, @@ -1047,7 +1046,6 @@ class Button(BaseComponent): self.icon_selected = Icon(icon_name=self.icon_name, icon_size=self.icon_size, icon_color=self.selected_icon_color) if self.is_icon_inline: - # TODO: Only apply screen_* at render if self.is_text_centered: # Shift the text's centering if self.text: @@ -1077,6 +1075,7 @@ class Button(BaseComponent): self.right_icon_y = math.ceil((self.height - self.right_icon.height)/2) + def render(self): if self.is_selected: background_color = self.selected_color diff --git a/src/seedsigner/gui/renderer.py b/src/seedsigner/gui/renderer.py index e0e321e5..cd3d031c 100644 --- a/src/seedsigner/gui/renderer.py +++ b/src/seedsigner/gui/renderer.py @@ -18,17 +18,13 @@ class Renderer(ConfigurableSingleton): @classmethod - def configure_instance(cls, config={}): + def configure_instance(cls): from seedsigner.models.settings import Settings - super().configure_instance(config) # Instantiate the one and only Renderer instance renderer = cls.__new__(cls) cls._instance = renderer - # TODO: Use Settings values to wire up diff hardware params - settings = Settings.get_instance() - # Eventually we'll be able to plug in other display controllers renderer.disp = ST7789() renderer.canvas_width = renderer.disp.width diff --git a/src/seedsigner/gui/screens/psbt_screens.py b/src/seedsigner/gui/screens/psbt_screens.py index 9cb482d2..62b606ef 100644 --- a/src/seedsigner/gui/screens/psbt_screens.py +++ b/src/seedsigner/gui/screens/psbt_screens.py @@ -38,7 +38,6 @@ class PSBTOverviewScreen(ButtonListScreen): # icon_text_lines_y = self.components[-1].screen_y + self.components[-1].height icon_text_lines_y = self.top_nav.height + GUIConstants.COMPONENT_PADDING - if not self.destination_addresses: # This is a self-transfer spend_amount = self.change_amount @@ -52,7 +51,7 @@ class PSBTOverviewScreen(ButtonListScreen): # Prep the transaction flow chart self.chart_x = 0 - self.chart_y = self.components[-1].screen_y + self.components[-1].height + GUIConstants.COMPONENT_PADDING + self.chart_y = self.components[-1].screen_y + self.components[-1].height + int(GUIConstants.COMPONENT_PADDING/2) chart_height = self.buttons[0].screen_y - self.chart_y - GUIConstants.COMPONENT_PADDING # We need to supersample the whole panel so that small/thin elements render @@ -70,7 +69,8 @@ class PSBTOverviewScreen(ButtonListScreen): font_size = GUIConstants.BODY_FONT_MIN_SIZE * ssf font = Fonts.get_font(GUIConstants.BODY_FONT_NAME, font_size) - tw, chart_text_height = font.getsize("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") # All possible chars for max range + # Measure from anchor "top" to include font pixels below baseline (e.g. the "g" in "change") + (left, top, right, chart_text_height) = font.getbbox(text="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", anchor="lt") vertical_center = int(image.height/2) # Supersampling renders thin elements poorly if they land on an even line before scaling down if vertical_center % 2 == 1: diff --git a/src/seedsigner/gui/screens/screen.py b/src/seedsigner/gui/screens/screen.py index dda658cf..ba64f741 100644 --- a/src/seedsigner/gui/screens/screen.py +++ b/src/seedsigner/gui/screens/screen.py @@ -56,8 +56,6 @@ class BaseScreen(BaseComponent): return self._run() except Exception as e: - print(e) - print("------") repr(e) raise e finally: @@ -214,7 +212,42 @@ class BaseTopNavScreen(BaseScreen): def _run(self): - raise Exception("Must implement in a child class") + while True: + if not self.top_nav.show_back_button and not self.top_nav.show_power_button: + # There's no navigation away from this screen; nothing to do here + time.sleep(0.1) + continue + + user_input = self.hw_inputs.wait_for( + HardwareButtonsConstants.ALL_KEYS, + check_release=True, + release_keys=HardwareButtonsConstants.KEYS__ANYCLICK + ) + + with self.renderer.lock: + if not self.top_nav.is_selected and user_input in [ + HardwareButtonsConstants.KEY_LEFT, + HardwareButtonsConstants.KEY_UP + ]: + self.top_nav.is_selected = True + self.top_nav.render_buttons() + + elif self.top_nav.is_selected and user_input in [ + HardwareButtonsConstants.KEY_DOWN, + HardwareButtonsConstants.KEY_RIGHT + ]: + self.top_nav.is_selected = False + self.top_nav.render_buttons() + + elif self.top_nav.is_selected and user_input in HardwareButtonsConstants.KEYS__ANYCLICK: + return self.top_nav.selected_button + + else: + # Nothing to do with this input + continue + + # Write the screen updates + self.renderer.show_image() @@ -810,6 +843,7 @@ class DireWarningScreen(WarningScreen): status_color: str = GUIConstants.DIRE_WARNING_COLOR + @dataclass class ResetScreen(BaseTopNavScreen): def __post_init__(self): @@ -822,10 +856,6 @@ class ResetScreen(BaseTopNavScreen): screen_y=self.top_nav.height, height=self.canvas_height - self.top_nav.height, )) - - def _run(self): - while True: - pass @@ -841,7 +871,3 @@ class PowerOffScreen(BaseTopNavScreen): screen_y=self.top_nav.height, height=self.canvas_height - self.top_nav.height, )) - - def _run(self): - while True: - pass diff --git a/src/seedsigner/gui/screens/settings_screens.py b/src/seedsigner/gui/screens/settings_screens.py index d7340ad4..7bfc729c 100644 --- a/src/seedsigner/gui/screens/settings_screens.py +++ b/src/seedsigner/gui/screens/settings_screens.py @@ -5,7 +5,7 @@ from typing import List from seedsigner.gui.components import Button, CheckboxButton, CheckedSelectionButton, FontAwesomeIconConstants, GUIConstants, IconButton, TextArea from seedsigner.gui.screens.scan_screens import ScanScreen -from seedsigner.gui.screens.screen import ButtonListScreen +from seedsigner.gui.screens.screen import BaseTopNavScreen, ButtonListScreen from seedsigner.hardware.buttons import HardwareButtonsConstants from seedsigner.models.settings import SettingsConstants @@ -190,3 +190,24 @@ class IOTestScreen(ScanScreen): cur_selected_button.is_selected = True time.sleep(0.1) + + + +@dataclass +class DonateScreen(BaseTopNavScreen): + def __post_init__(self): + self.title = "Donate" + super().__post_init__() + + self.components.append(TextArea( + text="SeedSigner is 100% free & open source, funded solely by the Bitcoin community.\n\nDonate onchain or LN at:", + screen_y=self.top_nav.height + 3*GUIConstants.COMPONENT_PADDING, + )) + + self.components.append(TextArea( + text="seedsigner.com", + font_size=GUIConstants.TOP_NAV_TITLE_FONT_SIZE + 8, + font_color=GUIConstants.ACCENT_COLOR, + supersampling_factor=1, + screen_y=self.components[-1].screen_y + self.components[-1].height + GUIConstants.COMPONENT_PADDING + )) diff --git a/src/seedsigner/models/decode_qr.py b/src/seedsigner/models/decode_qr.py index 7578ea9d..b0c034b2 100644 --- a/src/seedsigner/models/decode_qr.py +++ b/src/seedsigner/models/decode_qr.py @@ -60,8 +60,6 @@ class DecodeQR: qr_type = DecodeQR.detect_segment_type(data, wordlist_language_code=self.wordlist_language_code) - print(qr_type) - if self.qr_type == None: self.qr_type = qr_type @@ -97,6 +95,10 @@ class DecodeQR: elif self.qr_type != qr_type: raise Exception('QR Fragment Unexpected Type Change') + + if not self.decoder: + # Did not find any recognizable format + return DecodeQRStatus.INVALID # Process the binary formats first if self.qr_type == QRType.SEED__COMPACTSEEDQR: diff --git a/src/seedsigner/models/psbt_parser.py b/src/seedsigner/models/psbt_parser.py index c3518743..af29a882 100644 --- a/src/seedsigner/models/psbt_parser.py +++ b/src/seedsigner/models/psbt_parser.py @@ -58,7 +58,6 @@ class PSBTParser(): def _set_root(self): self.root = bip32.HDKey.from_seed(self.seed.seed_bytes, version=NETWORKS[SettingsConstants.map_network_to_embit(self.network)]["xprv"]) - print(f"root: {self.root}") def parse(self): @@ -85,7 +84,6 @@ class PSBTParser(): def _parse_inputs(self): self.input_amount = 0 - print(f"psbt.inputs: {self.psbt.inputs}") self.num_inputs = len(self.psbt.inputs) for inp in self.psbt.inputs: if inp.witness_utxo: @@ -343,5 +341,5 @@ class PSBTParser(): i = change_data["output_index"] output = self.psbt.outputs[i] is_owner = descriptor.owns(output) - print(f"{self.psbt.tx.vout[i].script_pubkey.address()} | {output.value} | {is_owner}") + # print(f"{self.psbt.tx.vout[i].script_pubkey.address()} | {output.value} | {is_owner}") return is_owner diff --git a/src/seedsigner/models/settings_definition.py b/src/seedsigner/models/settings_definition.py index cf1f009a..4687e1fa 100644 --- a/src/seedsigner/models/settings_definition.py +++ b/src/seedsigner/models/settings_definition.py @@ -513,8 +513,6 @@ class SettingsDefinition: if __name__ == "__main__": import json - import os - print("Exporting SettingsDefinition to json") output_file = "settings_definition.json" with open(output_file, 'w') as json_file: diff --git a/src/seedsigner/resources/fonts/seedsigner-glyphs.otf b/src/seedsigner/resources/fonts/seedsigner-glyphs.otf index 3edea9f59c909e2ab0a38c20c7c3f24e43d5dbc3..63a0008cdca20b42e9f41981c9b8b46f5dc3c058 100644 GIT binary patch literal 11808 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 BKcD~r diff --git a/src/seedsigner/views/psbt_views.py b/src/seedsigner/views/psbt_views.py index ced51a9b..ec198129 100644 --- a/src/seedsigner/views/psbt_views.py +++ b/src/seedsigner/views/psbt_views.py @@ -109,7 +109,7 @@ class PSBTOverviewView(View): num_change_outputs = 0 num_self_transfer_outputs = 0 for change_output in change_data: - print(f"""{change_output["derivation_path"][0]}""") + # print(f"""{change_output["derivation_path"][0]}""") if change_output["derivation_path"][0].split("/")[-2] == "1": num_change_outputs += 1 else: @@ -277,8 +277,6 @@ class PSBTChangeDetailsView(View): # Single-sig verification is easy. We expect to find a single fingerprint # and derivation path. seed_fingerprint = self.controller.psbt_seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK)) - print(f"seed fingerprint: {seed_fingerprint}") - print(change_data) if seed_fingerprint not in change_data.get("fingerprint"): # TODO: Something is wrong with this psbt(?). Reroute to warning? diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index da7b2bab..1179af00 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -256,7 +256,6 @@ class SeedReviewPassphraseView(View): def __init__(self): super().__init__() self.seed = self.controller.storage.get_pending_seed() - print(f"SeedReviewPassphraseView self.seed: {self.seed}") def run(self): @@ -348,7 +347,7 @@ class SeedOptionsView(View): REVIEW_PSBT = "Review PSBT" VERIFY_ADDRESS = "Verify Addr" EXPORT_XPUB = "Export Xpub" - BACKUP = ("Backup Seed", None, None, None, FontAwesomeIconConstants.CIRCLE_CHEVRON_RIGHT) + BACKUP = ("Backup Seed", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT) DISCARD = ("Discard Seed", None, None, "red") button_data = [] @@ -366,7 +365,7 @@ class SeedOptionsView(View): if self.controller.psbt: if PSBTParser.has_matching_input_fingerprint(self.controller.psbt, self.seed, network=self.settings.get_value(SettingsConstants.SETTING__NETWORK)): if self.controller.resume_main_flow and self.controller.resume_main_flow == Controller.FLOW__PSBT: - # Re-route us directly back to the start of the PSBT flow + # Re-route us directly back to the start of the PSBT flow self.controller.resume_main_flow = None self.controller.psbt_seed = self.seed return Destination(PSBTOverviewView, skip_current_view=True) @@ -1122,9 +1121,6 @@ class AddressVerificationStartView(View): self.controller.unverified_address["sig_type"] = sig_type self.controller.unverified_address["derivation_path"] = derivation_path - import json - print(json.dumps(self.controller.unverified_address, indent=4)) - return destination @@ -1332,8 +1328,6 @@ class SeedAddressVerificationView(View): # Successfully verified the addr; update the data self.controller.unverified_address["verified_index"] = self.verified_index.cur_count self.controller.unverified_address["verified_index_is_change"] = self.verified_index_is_change.cur_count == 1 - import json - print(json.dumps(self.controller.unverified_address, indent=4)) return Destination(AddressVerificationSuccessView, view_args=dict(seed_num=self.seed_num)) else: @@ -1379,14 +1373,12 @@ class SeedAddressVerificationView(View): (receive_address, change_address) = self.derive_single_sig(i) if self.address == receive_address: - print(f"Verified receive addr #{i}!") self.verified_index.set_value(i) self.verified_index_is_change.set_value(0) self.keep_running = False break elif self.address == change_address: - print(f"Verified change addr #{i}!") self.verified_index.set_value(i) self.verified_index_is_change.set_value(1) self.keep_running = False @@ -1490,8 +1482,6 @@ class MultisigWalletDescriptorView(View): policy = descriptor.brief_policy.split("multisig")[0].strip() - print(fingerprints) - RETURN = "Return to PSBT" VERIFY = "Verify Addr" OK = "OK" diff --git a/src/seedsigner/views/settings_views.py b/src/seedsigner/views/settings_views.py index e3c46b31..5a705e08 100644 --- a/src/seedsigner/views/settings_views.py +++ b/src/seedsigner/views/settings_views.py @@ -1,4 +1,4 @@ -from seedsigner.gui.components import FontAwesomeIconConstants +from seedsigner.gui.components import FontAwesomeIconConstants, SeedSignerCustomIconConstants from seedsigner.models.decode_qr import DecodeQR from .view import View, Destination, BackStackView, MainMenuView @@ -16,6 +16,9 @@ class SettingsMenuView(View): def run(self): + IO_TEST = "I/O test" + DONATE = "Donate" + settings_entries = SettingsDefinition.get_settings_entries( visibiilty=self.visibility ) @@ -32,16 +35,17 @@ class SettingsMenuView(View): title = "Settings" # Set up the next nested level of menuing - button_data.append(("Advanced", None, None, None, FontAwesomeIconConstants.CIRCLE_CHEVRON_RIGHT)) + button_data.append(("Advanced", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT)) next = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__ADVANCED}) - button_data.append("I/O test") + button_data.append(IO_TEST) + button_data.append(DONATE) elif self.visibility == SettingsConstants.VISIBILITY__ADVANCED: title = "Advanced" # So far there are no real Developer options; disabling for now - # button_data.append(("Developer Options", None, None, None, FontAwesomeIconConstants.CIRCLE_CHEVRON_RIGHT)) + # button_data.append(("Developer Options", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT)) # next = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__DEVELOPER}) next = None @@ -67,9 +71,12 @@ class SettingsMenuView(View): elif selected_menu_num == len(settings_entries): return next - elif selected_menu_num == len(settings_entries) + 1: + elif len(button_data) > selected_menu_num and button_data[selected_menu_num] == IO_TEST: return Destination(IOTestView) + elif len(button_data) > selected_menu_num and button_data[selected_menu_num] == DONATE: + return Destination(DonateView) + else: # TODO: Free-entry types (are there any?) will need their own SettingsEntryUpdateFreeEntryView(?). return Destination(SettingsEntryUpdateSelectionView, view_args={"attr_name": settings_entries[selected_menu_num].attr_name}) @@ -179,3 +186,11 @@ class IOTestView(View): ).display() return Destination(SettingsMenuView) + + + +class DonateView(View): + def run(self): + settings_screens.DonateScreen().display() + + return Destination(SettingsMenuView) diff --git a/src/seedsigner/views/tools_views.py b/src/seedsigner/views/tools_views.py index bcc8c2f8..8c6b2216 100644 --- a/src/seedsigner/views/tools_views.py +++ b/src/seedsigner/views/tools_views.py @@ -4,7 +4,6 @@ import time from PIL import Image from PIL.ImageOps import autocontrast -from seedsigner.gui.screens.screen import LargeButtonScreen from seedsigner.hardware.camera import Camera from seedsigner.gui.components import FontAwesomeIconConstants @@ -13,9 +12,9 @@ from seedsigner.gui.screens.tools_screens import ToolsDiceEntropyEntryScreen, To from seedsigner.helpers import mnemonic_generation from seedsigner.models.seed import Seed from seedsigner.models.settings_definition import SettingsConstants -from seedsigner.views.seed_views import SeedDiscardView, SeedFinalizeView, SeedMnemonicEntryView, SeedWordsView, SeedWordsWarningView +from seedsigner.views.seed_views import SeedDiscardView, SeedFinalizeView, SeedMnemonicEntryView, SeedWordsWarningView -from .view import NotYetImplementedView, View, Destination, BackStackView, MainMenuView +from .view import View, Destination, BackStackView @@ -207,9 +206,9 @@ class ToolsDiceEntropyEntryView(View): if ret == RET_CODE__BACK_BUTTON: return Destination(BackStackView) - print(ret) + print(f"Dice rolls: {ret}") dice_seed_phrase = mnemonic_generation.generate_mnemonic_from_dice(ret) - print(dice_seed_phrase) + print(f"""Mnemonic: "{dice_seed_phrase}" """) # Add the mnemonic as an in-memory Seed seed = Seed(dice_seed_phrase, wordlist_language_code=self.settings.get_value(SettingsConstants.SETTING__WORDLIST_LANGUAGE)) diff --git a/tests/test_controller.py b/tests/test_controller.py index ef3e7ea3..b6887369 100644 --- a/tests/test_controller.py +++ b/tests/test_controller.py @@ -3,6 +3,7 @@ import pytest from mock import MagicMock from seedsigner.controller import Controller from seedsigner.models.settings import Settings +from seedsigner.models.settings_definition import SettingsConstants @@ -11,10 +12,6 @@ def test_singleton_init_fails(): with pytest.raises(Exception): c = Controller() -def test_singleton_get_instance_without_configure_fails(): - """ Calling get_instance() without first calling configure_instance() should fail """ - with pytest.raises(Exception): - c = Controller.get_instance() def test_singleton_get_instance_preserves_state(): """ Changes to the Controller singleton should be preserved across calls to get_instance() """ @@ -25,38 +22,17 @@ def test_singleton_get_instance_preserves_state(): Settings._instance = None Controller._instance = None - settings = """ - [system] - debug = False - default_language = en - persistent_settings = False - - [display] - text_color = ORANGE - qr_background_color = FFFFFF - camera_rotation = 0 - - [wallet] - network = main - software = Prompt - qr_density = 2 - custom_derivation = m/0/0 - compact_seedqr_enabled = False - """ - config = configparser.ConfigParser() - config.read_string(settings) - # Initialize the instance and verify that it read the config settings - Controller.configure_instance(config, disable_hardware=True) + Controller.configure_instance(disable_hardware=True) controller = Controller.get_instance() - assert controller.color == "ORANGE" + assert controller.unverified_address is None # Change a value in the instance... - controller.color = "purple" + controller.unverified_address = "123abc" # ...get a new copy of the instance and confirm change controller = Controller.get_instance() - assert controller.color == "purple" + assert controller.unverified_address == "123abc" def test_missing_settings_get_defaults(): @@ -69,30 +45,9 @@ def test_missing_settings_get_defaults(): Settings._instance = None Controller._instance = None - # Intentionally omit `compact_seedqr_enabled` from settings: - settings = """ - [system] - debug = False - default_language = en - persistent_settings = False - - [display] - text_color = ORANGE - qr_background_color = FFFFFF - camera_rotation = 0 - - [wallet] - network = main - software = Prompt - qr_density = 2 - custom_derivation = m/0/0 - """ - config = configparser.ConfigParser() - config.read_string(settings) - # Controller should parse the settings fine, even though a field is missing - Controller.configure_instance(config, disable_hardware=True) + Controller.configure_instance(disable_hardware=True) # Controller should still have a default value controller = Controller.get_instance() - assert controller.settings.compact_seedqr_enabled is False + assert controller.settings.get_value(SettingsConstants.SETTING__COMPACT_SEEDQR) == SettingsConstants.OPTION__DISABLED diff --git a/tests/test_decodepsbtqr.py b/tests/test_decodepsbtqr.py index 4891c882..ef9baa4a 100644 --- a/tests/test_decodepsbtqr.py +++ b/tests/test_decodepsbtqr.py @@ -3,6 +3,8 @@ from mock import MagicMock from seedsigner.models import Seed, DecodeQR, DecodeQRStatus, QRType, PSBTParser from embit import psbt, bip39 +from seedsigner.models.settings_definition import SettingsConstants + # this is an of this bug: https://github.com/Foundation-Devices/foundation-ur-py/issues/3 @@ -78,15 +80,15 @@ def test_base64_single_frame_singlsig(): assert str(tx) == base64_psbt - mnemonic = "height demise useless trap grow lion found off key clown transfer enroll" + mnemonic = "height demise useless trap grow lion found off key clown transfer enroll".split() pw = "" seed = Seed(mnemonic, passphrase=pw) - assert seed.mnemonic_str == mnemonic + assert seed.mnemonic_str == " ".join(mnemonic) assert seed.seed_bytes != None - pp = PSBTParser(tx,seed,"test") + pp = PSBTParser(p=tx, seed=seed, network=SettingsConstants.TESTNET) assert tx.inputs[0].witness_utxo.value == 25000 # input amount in psbt @@ -135,8 +137,8 @@ def test_base64_2_input_p2wsh(): assert str(tx) == base64_psbt - mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" - pp = PSBTParser(tx, Seed(mnemonic), "test") + mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".split() + pp = PSBTParser(p=tx, seed=Seed(mnemonic), network=SettingsConstants.TESTNET) assert tx.inputs[0].witness_utxo.value == 10000000 # input amount 1 in psbt @@ -162,8 +164,8 @@ def test_base64_1_input_p2sh_p2wsh(): assert str(tx) == base64_psbt - mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" - pp = PSBTParser(tx,Seed(mnemonic, wordlist=bip39.WORDLIST),"test") + mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".split() + pp = PSBTParser(p=tx, seed=Seed(mnemonic), network=SettingsConstants.TESTNET) assert tx.inputs[0].witness_utxo.value == 100000000 # input amount 1 in psbt @@ -175,62 +177,6 @@ def test_base64_1_input_p2sh_p2wsh(): assert len(pp.destination_addresses) == 1 -def test_ur_legacy(): - - qrcodes = [ - "UR:BYTES/2OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3DJV07U94KMSQQQQQQQQZQ8A0CQSYQQQQQQQZQHA78FG5TANFV9Z2TPDWE57AUVCN2T06TDGCAJNYPAT9LVG5QFMU5QSQQQQQRLLLLLL3NZ3KK6TMJ2TTRH6SKU05V76GHEANAT2QSDCDPFG67YZQQPFFZKSZQQQQQQ0LLLLLUPYQRGRQQQQQQQQYGQZP4XCCZ3WFNWK" - , "UR:BYTES/2OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3DJV07U94KMSQQQQQQQQZQ8A0CQSYQQQQQQQZQHA78FG5TANFV9Z2TPDWE57AUVCN2T06TDGCAJNYPAT9LVG5QFMU5QSQQQQQRLLLLLL3NZ3KK6TMJ2TTRH6SKU05V76GHEANAT2QSDCDPFG67YZQQPFFZKSZQQQQQQ0LLLLLUPYQRGRQQQQQQQQYGQZP4XCCZ3WFNWK" - , "UR:BYTES/3OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GMPEQQQQQQQQQQ9SQZSRR3CY9AYW5V4Y0A5DMWD57JD7FXX9G95PYWVZYQGSX2Y0YENNVNLEHXVMTDS86QM4VNDHG9V0K3PNDMGAJLWLSTS6504SZYP80TGGDPFZR8AM7XZNM77XWKRHP0D0Y540FLPTA5C2HRUQ0" - , "UR:BYTES/3OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GMPEQQQQQQQQQQ9SQZSRR3CY9AYW5V4Y0A5DMWD57JD7FXX9G95PYWVZYQGSX2Y0YENNVNLEHXVMTDS86QM4VNDHG9V0K3PNDMGAJLWLSTS6504SZYP80TGGDPFZR8AM7XZNM77XWKRHP0D0Y540FLPTA5C2HRUQ0" - , "UR:BYTES/3OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GMPEQQQQQQQQQQ9SQZSRR3CY9AYW5V4Y0A5DMWD57JD7FXX9G95PYWVZYQGSX2Y0YENNVNLEHXVMTDS86QM4VNDHG9V0K3PNDMGAJLWLSTS6504SZYP80TGGDPFZR8AM7XZNM77XWKRHP0D0Y540FLPTA5C2HRUQ0" - , "UR:BYTES/4OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3Y0PYQFPQW6EJAC7ZGZUYVSCVLPJUS8CVFT8389KFXX82VM3YQMT26FRVHLVUQJ8XPZQYGR9FH3H26HSK99ZH3MQ4D7EHCS7Y752EP37HGG2X6RU5V3PKD7PMSPZQF9L7DESNZNS0H4V56978HCMAEG9D99CNY5LYCV247F58T7M66QUQYSS907LVPMZLKYAWMDGRRKT" - , "UR:BYTES/4OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3Y0PYQFPQW6EJAC7ZGZUYVSCVLPJUS8CVFT8389KFXX82VM3YQMT26FRVHLVUQJ8XPZQYGR9FH3H26HSK99ZH3MQ4D7EHCS7Y752EP37HGG2X6RU5V3PKD7PMSPZQF9L7DESNZNS0H4V56978HCMAEG9D99CNY5LYCV247F58T7M66QUQYSS907LVPMZLKYAWMDGRRKT" - , "UR:BYTES/5OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/GX8KAW6FYVRQ2HKD5T4WUJJ7K68T5262QQQQQQQPQY45QRGRQQQQQQQQYGQZP4XCCZ3WFNWK0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GQYZ5W53PQFMWVTS2CUAWJ43C87WR6ZZ705V5LU2AEKGEF8AM8FWP6TQFTD7AZGGZMKAVTUW8HDRTKMEET55FK6MX" - , "UR:BYTES/5OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/GX8KAW6FYVRQ2HKD5T4WUJJ7K68T5262QQQQQQQPQY45QRGRQQQQQQQQYGQZP4XCCZ3WFNWK0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GQYZ5W53PQFMWVTS2CUAWJ43C87WR6ZZ705V5LU2AEKGEF8AM8FWP6TQFTD7AZGGZMKAVTUW8HDRTKMEET55FK6MX" - , "UR:BYTES/5OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/GX8KAW6FYVRQ2HKD5T4WUJJ7K68T5262QQQQQQQPQY45QRGRQQQQQQQQYGQZP4XCCZ3WFNWK0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GQYZ5W53PQFMWVTS2CUAWJ43C87WR6ZZ705V5LU2AEKGEF8AM8FWP6TQFTD7AZGGZMKAVTUW8HDRTKMEET55FK6MX" - , "UR:BYTES/6OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/KTS8U3XQP95WYR8VQ9V2KWHCTS399T3ZQCP8DE3WPTRN462K8QLEC0GGTE73JNL3THXER9YLHVA9C8FVP9DHM5GUKUGYR2PSQQQGQQGQQZQQQQQQSQPQQQYQQQQQQQQRQQQQQGSXQTWM4303C7A5DWM089WJ3XMTV6EWQLJYCQYK3CSVASQ432E6LPWZY8XYUTHDXVQQ" - , "UR:BYTES/6OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/KTS8U3XQP95WYR8VQ9V2KWHCTS399T3ZQCP8DE3WPTRN462K8QLEC0GGTE73JNL3THXER9YLHVA9C8FVP9DHM5GUKUGYR2PSQQQGQQGQQZQQQQQQSQPQQQYQQQQQQQQRQQQQQGSXQTWM4303C7A5DWM089WJ3XMTV6EWQLJYCQYK3CSVASQ432E6LPWZY8XYUTHDXVQQ" - , "UR:BYTES/7OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/QZQQZQQQSQQQQQYQQGQQPQQQQQQQQQCQQQQQQQQPQ9R4YGGZDYQESZAAQHLY3L9L5VMSYRCQAXPWR6ES83NEC5XTMD4HPKVNGF4ZZQ4XNF7SKKG5KVH0UZPD3XXVNDWVP2CQAP0GLNRGQP2DHAD0U9HYLAF2UGSZQF5SRXQTH5ZLUJ8UH73NWQS0QR5C9C0TXQ7X08ZS" - , "UR:BYTES/7OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/QZQQZQQQSQQQQQYQQGQQPQQQQQQQQQCQQQQQQQQPQ9R4YGGZDYQESZAAQHLY3L9L5VMSYRCQAXPWR6ES83NEC5XTMD4HPKVNGF4ZZQ4XNF7SKKG5KVH0UZPD3XXVNDWVP2CQAP0GLNRGQP2DHAD0U9HYLAF2UGSZQF5SRXQTH5ZLUJ8UH73NWQS0QR5C9C0TXQ7X08ZS" - , "UR:BYTES/1OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/TYPUUURNVF607QGQ05PQQQQQQ9VXGQQDUMWH3LD9GH8XF4ZYJQNMQ80L6MC0KMV6JMVV22RDPZP0SQQQQQQQPLLLLLLSYS8ZQYQQQQQQQQTQQ9P6MG599TND0NJ54AZSE0ZHSHLY7Q4P94C79GQSQQQQQQQZYQPQ68Q0NLXPZYTUVURY6X4G8U7T5H4QVCHY3KKXAW0R" - , "UR:BYTES/1OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/TYPUUURNVF607QGQ05PQQQQQQ9VXGQQDUMWH3LD9GH8XF4ZYJQNMQ80L6MC0KMV6JMVV22RDPZP0SQQQQQQQPLLLLLLSYS8ZQYQQQQQQQQTQQ9P6MG599TND0NJ54AZSE0ZHSHLY7Q4P94C79GQSQQQQQQQZYQPQ68Q0NLXPZYTUVURY6X4G8U7T5H4QVCHY3KKXAW0R" - , "UR:BYTES/2OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3DJV07U94KMSQQQQQQQQZQ8A0CQSYQQQQQQQZQHA78FG5TANFV9Z2TPDWE57AUVCN2T06TDGCAJNYPAT9LVG5QFMU5QSQQQQQRLLLLLL3NZ3KK6TMJ2TTRH6SKU05V76GHEANAT2QSDCDPFG67YZQQPFFZKSZQQQQQQ0LLLLLUPYQRGRQQQQQQQQYGQZP4XCCZ3WFNWK" - , "UR:BYTES/2OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3DJV07U94KMSQQQQQQQQZQ8A0CQSYQQQQQQQZQHA78FG5TANFV9Z2TPDWE57AUVCN2T06TDGCAJNYPAT9LVG5QFMU5QSQQQQQRLLLLLL3NZ3KK6TMJ2TTRH6SKU05V76GHEANAT2QSDCDPFG67YZQQPFFZKSZQQQQQQ0LLLLLUPYQRGRQQQQQQQQYGQZP4XCCZ3WFNWK" - , "UR:BYTES/3OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GMPEQQQQQQQQQQ9SQZSRR3CY9AYW5V4Y0A5DMWD57JD7FXX9G95PYWVZYQGSX2Y0YENNVNLEHXVMTDS86QM4VNDHG9V0K3PNDMGAJLWLSTS6504SZYP80TGGDPFZR8AM7XZNM77XWKRHP0D0Y540FLPTA5C2HRUQ0" - , "UR:BYTES/3OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GMPEQQQQQQQQQQ9SQZSRR3CY9AYW5V4Y0A5DMWD57JD7FXX9G95PYWVZYQGSX2Y0YENNVNLEHXVMTDS86QM4VNDHG9V0K3PNDMGAJLWLSTS6504SZYP80TGGDPFZR8AM7XZNM77XWKRHP0D0Y540FLPTA5C2HRUQ0" - , "UR:BYTES/3OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/0QXPCDECDVJ8PS0DPW59YDWSH262DUZV6VAT4E4GMPEQQQQQQQQQQ9SQZSRR3CY9AYW5V4Y0A5DMWD57JD7FXX9G95PYWVZYQGSX2Y0YENNVNLEHXVMTDS86QM4VNDHG9V0K3PNDMGAJLWLSTS6504SZYP80TGGDPFZR8AM7XZNM77XWKRHP0D0Y540FLPTA5C2HRUQ0" - , "UR:BYTES/4OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3Y0PYQFPQW6EJAC7ZGZUYVSCVLPJUS8CVFT8389KFXX82VM3YQMT26FRVHLVUQJ8XPZQYGR9FH3H26HSK99ZH3MQ4D7EHCS7Y752EP37HGG2X6RU5V3PKD7PMSPZQF9L7DESNZNS0H4V56978HCMAEG9D99CNY5LYCV247F58T7M66QUQYSS907LVPMZLKYAWMDGRRKT" - , "UR:BYTES/4OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/3Y0PYQFPQW6EJAC7ZGZUYVSCVLPJUS8CVFT8389KFXX82VM3YQMT26FRVHLVUQJ8XPZQYGR9FH3H26HSK99ZH3MQ4D7EHCS7Y752EP37HGG2X6RU5V3PKD7PMSPZQF9L7DESNZNS0H4V56978HCMAEG9D99CNY5LYCV247F58T7M66QUQYSS907LVPMZLKYAWMDGRRKT" - , "UR:BYTES/6OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/KTS8U3XQP95WYR8VQ9V2KWHCTS399T3ZQCP8DE3WPTRN462K8QLEC0GGTE73JNL3THXER9YLHVA9C8FVP9DHM5GUKUGYR2PSQQQGQQGQQZQQQQQQSQPQQQYQQQQQQQQRQQQQQGSXQTWM4303C7A5DWM089WJ3XMTV6EWQLJYCQYK3CSVASQ432E6LPWZY8XYUTHDXVQQ" - , "UR:BYTES/7OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/QZQQZQQQSQQQQQYQQGQQPQQQQQQQQQCQQQQQQQQPQ9R4YGGZDYQESZAAQHLY3L9L5VMSYRCQAXPWR6ES83NEC5XTMD4HPKVNGF4ZZQ4XNF7SKKG5KVH0UZPD3XXVNDWVP2CQAP0GLNRGQP2DHAD0U9HYLAF2UGSZQF5SRXQTH5ZLUJ8UH73NWQS0QR5C9C0TXQ7X08ZS" - , "UR:BYTES/7OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/QZQQZQQQSQQQQQYQQGQQPQQQQQQQQQCQQQQQQQQPQ9R4YGGZDYQESZAAQHLY3L9L5VMSYRCQAXPWR6ES83NEC5XTMD4HPKVNGF4ZZQ4XNF7SKKG5KVH0UZPD3XXVNDWVP2CQAP0GLNRGQP2DHAD0U9HYLAF2UGSZQF5SRXQTH5ZLUJ8UH73NWQS0QR5C9C0TXQ7X08ZS" - , "UR:BYTES/8OF8/MMH5LDF9RK3QKCUL3VM26M6270FFJU50CU6YT5WM65783GL5EJMQPG3WV3/E0DKKUXEJDPX589HZPQ6SVQQQZQQZQQQSQQQQQYQQGQQPQQPQQQQQPQQQQQZYQSZ56D86Z6EZJEJALSG9KYCEJD4ES9TQR59AR7VDQQ9FKL44LSKUNL3E38ZAMFNQQQQSQQSQQYQQQQQPQQZQQQGQQGQQQQQGQQQQQQQ0P6SEH" - ] - - d = DecodeQR() - for i in qrcodes: - if d.add_data(i) == DecodeQRStatus.COMPLETE: - break - assert d.qr_type == QRType.PSBT__LEGACY_UR - - #complete should be true - assert d.is_complete - - tx = d.get_psbt() - - mnemonic = "zone zone zone zone zone abandon ability able abandon ability able abstract" - pp = PSBTParser(tx,Seed(mnemonic, wordlist=bip39.WORDLIST),"test") - - assert pp.input_amount == 200000 - - assert pp.fee_amount == 226 - - assert pp.spend_amount == 123456 - - assert pp.change_amount == (pp.input_amount - pp.spend_amount - pp.fee_amount) - - assert pp.change_amount == 76318 - def test_specter_multisig_animated_qr(): qrcodes = [ @@ -252,8 +198,8 @@ def test_specter_multisig_animated_qr(): tx = d.get_psbt() - mnemonic = "zone zone zone zone zone abandon ability able abandon ability able abstract" - pp = PSBTParser(tx,Seed(mnemonic, wordlist=bip39.WORDLIST),"test") + mnemonic = "zone zone zone zone zone abandon ability able abandon ability able abstract".split() + pp = PSBTParser(p=tx, seed=Seed(mnemonic), network=SettingsConstants.TESTNET) assert pp.input_amount == 1052818 @@ -290,8 +236,8 @@ def test_specter_multisig_animated_qr(): tx2 = d2.get_psbt() - mnemonic2 = "able bacon cable able bacon cable abandon abandon abandon abandon abandon access" - pp2 = PSBTParser(tx2,Seed(mnemonic2, wordlist=bip39.WORDLIST),"test") + mnemonic2 = "able bacon cable able bacon cable abandon abandon abandon abandon abandon access".split() + pp2 = PSBTParser(p=tx2, seed=Seed(mnemonic2), network=SettingsConstants.TESTNET) assert pp2.input_amount == 1052818 @@ -334,8 +280,8 @@ def test_short_4_letter_mnemonic_qr(): assert d.is_complete assert d.get_seed_phrase() == ["height", "demise", "useless", "trap", "grow", "lion", "found", "off", "key", "clown", "transfer", "enroll"] -def test_bitcoin_address(): - + +def test_bitcoin_address(): bad1 = "loremipsum" bad2 = "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" bad3 = "121802020768124106400009195602431595117715840445" @@ -361,49 +307,44 @@ def test_bitcoin_address(): d.add_data(legacy_address1) assert d.get_address() == legacy_address1 - assert d.get_address_type() == "P2PKH-main" + assert d.get_address_type() == (SettingsConstants.LEGACY_P2PKH, SettingsConstants.MAINNET) d = DecodeQR() d.add_data(legacy_address2) assert d.get_address() == legacy_address2 - assert d.get_address_type() == "P2PKH-main" + assert d.get_address_type() == (SettingsConstants.LEGACY_P2PKH, SettingsConstants.MAINNET) d = DecodeQR() d.add_data(main_bech32_address) assert d.get_address() == main_bech32_address - assert d.get_address_type() == "Bech32-main" + assert d.get_address_type() == (SettingsConstants.NATIVE_SEGWIT, SettingsConstants.MAINNET) d = DecodeQR() d.add_data(test_bech32_address) assert d.get_address() == test_bech32_address - assert d.get_address_type() == "Bech32-test" + assert d.get_address_type() == (SettingsConstants.NATIVE_SEGWIT, SettingsConstants.TESTNET) d = DecodeQR() d.add_data(main_nested_segwit_address) assert d.get_address() == main_nested_segwit_address - assert d.get_address_type() == "P2SH-main" + assert d.get_address_type() == (SettingsConstants.NESTED_SEGWIT, SettingsConstants.MAINNET) d = DecodeQR() d.add_data(test_nested_segwit_address) - + assert d.get_address() == test_nested_segwit_address - assert d.get_address_type() == "P2SH-test" - + assert d.get_address_type() == (SettingsConstants.NESTED_SEGWIT, SettingsConstants.TESTNET) + d = DecodeQR() d.add_data(main_bech32_address2) assert d.get_address() == "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq" - assert d.get_address_type() == "Bech32-main" - - d = DecodeQR() - d.add_data(main_bech32_address3) - - assert d.get_address() == "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq" - assert d.get_address_type() == "Bech32-main" + assert d.get_address_type() == (SettingsConstants.NATIVE_SEGWIT, SettingsConstants.MAINNET) + def test_seed_qr(): diff --git a/tests/test_encodepsbtqr.py b/tests/test_encodepsbtqr.py index 71a7a3b3..380a446d 100644 --- a/tests/test_encodepsbtqr.py +++ b/tests/test_encodepsbtqr.py @@ -1,7 +1,7 @@ import pytest from mock import MagicMock -from seedsigner.models import EncodeQR, QRType, EncodeQRDensity -from embit import psbt, bip39 +from seedsigner.models import EncodeQR, QRType +from embit import psbt from binascii import a2b_base64 from seedsigner.models.settings import SettingsConstants @@ -9,7 +9,6 @@ from seedsigner.models.settings import SettingsConstants def test_ur_qr_encode(): - base64_psbt = "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" tx = psbt.PSBT.parse(a2b_base64(base64_psbt)) @@ -23,8 +22,8 @@ def test_ur_qr_encode(): cnt += 1 -def test_specter_qr_encode(): +def test_specter_qr_encode(): base64_psbt = "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" tx = psbt.PSBT.parse(a2b_base64(base64_psbt)) @@ -60,43 +59,54 @@ def test_specter_qr_encode(): img = e.part_to_image(fragment) cnt += 1 -def test_seedsigner_qr(): + +def test_seedsigner_qr(): mnemonic = "obscure bone gas open exotic abuse virus bunker shuffle nasty ship dash" - e = EncodeQR(seed_phrase=mnemonic.split(" "), qr_type=QRType.SEED__SEEDQR) + e = EncodeQR(seed_phrase=mnemonic.split(), qr_type=QRType.SEED__SEEDQR) print(e.next_part()) assert e.next_part() == "121802020768124106400009195602431595117715840445" -def test_xpub_qr(): + +def test_xpub_qr(): mnemonic = "obscure bone gas open exotic abuse virus bunker shuffle nasty ship dash" - e = EncodeQR(seed_phrase=mnemonic.split(" "), passphrase="pass", qr_type=QRType.XPUB, network="test", derivation="m/48h/1h/0h/2h") + e = EncodeQR(seed_phrase=mnemonic.split(), passphrase="pass", qr_type=QRType.XPUB, network=SettingsConstants.TESTNET, derivation="m/48h/1h/0h/2h") assert e.next_part() == "[c49122a5/48h/1h/0h/2h]Vpub5mXgECaX5yYDNc5VnUG4jVNptyEg65qUjuofWchQeuMWWiq8rcPBoMxfrVggXj5NJmaNEToWpax8GMMucozvAdqf1bW1JsZsfdBzsK3VUC5" -def test_specter_xpub_qr(): + +def test_specter_xpub_qr(): mnemonic = "obscure bone gas open exotic abuse virus bunker shuffle nasty ship dash" - e = EncodeQR(seed_phrase=mnemonic.split(" "), passphrase="pass", qr_type=QRType.XPUB__SPECTER, network="test", derivation="m/48h/1h/0h/2h", qr_density=SettingsConstants.DENSITY__LOW) + e = EncodeQR(seed_phrase=mnemonic.split(" "), passphrase="pass", qr_type=QRType.XPUB__SPECTER, network=SettingsConstants.TESTNET, derivation="m/48h/1h/0h/2h", qr_density=SettingsConstants.DENSITY__LOW) assert e.next_part() == "p1of4 [c49122a5/48h/1h/0h/2h]Vpub5mXgECaX5yYDN" assert e.next_part() == "p2of4 c5VnUG4jVNptyEg65qUjuofWchQeuMWWiq8rcPBo" assert e.next_part() == "p3of4 MxfrVggXj5NJmaNEToWpax8GMMucozvAdqf1bW1J" assert e.next_part() == "p4of4 sZsfdBzsK3VUC5" -def test_ur_xpub_qr(): - + + +def test_ur_xpub_qr(): mnemonic = "obscure bone gas open exotic abuse virus bunker shuffle nasty ship dash" - e = EncodeQR(seed_phrase=mnemonic.split(" "), passphrase="pass", qr_type=QRType.XPUB__UR, network="test", derivation="m/48h/1h/0h/2h", qr_density=SettingsConstants.DENSITY__MEDIUM) + e = EncodeQR( + seed_phrase=mnemonic.split(), + passphrase="pass", + qr_type=QRType.XPUB__UR, + network=SettingsConstants.TESTNET, + derivation="m/48h/1h/0h/2h", + qr_density=SettingsConstants.DENSITY__MEDIUM + ) + # TODO: For Nick assert e.next_part() == "UR:CRYPTO-ACCOUNT/1-4/LPADAACSJKCYYNRDRTYAHDCAOEADCYSSMECPONAOLYTAADMETAADDLOXAXHDCLAOKSRLNLKPUEGYATHPMNRTAAOLAH" assert e.next_part() == "UR:CRYPTO-ACCOUNT/2-4/LPAOAACSJKCYYNRDRTYAHDCASNKKGHZMLUZORPVDGUOTECSTTKTOLPCWPTNTLKZTTIZTBEAAHDCXVDTPMYQDLAWNGL" assert e.next_part() == "UR:CRYPTO-ACCOUNT/3-4/LPAXAACSJKCYYNRDRTYAHDCARSTDSPZSBZSPGERLGDATUYNLPYBTGYIYYKBTWTAOSWKSVTSGCHBYDKYAVDSEPDJLAT" assert e.next_part() == "UR:CRYPTO-ACCOUNT/4-4/LPAAAACSJKCYYNRDRTYAHDCAAMTAADDYOEADLOCSDYYKADYKAEYKAOYKAOCYSSMECPONAYCYIOREKKJKAECADRRKIE" - diff --git a/tests/test_seed.py b/tests/test_seed.py index cc5eeaa3..45e597eb 100644 --- a/tests/test_seed.py +++ b/tests/test_seed.py @@ -6,10 +6,11 @@ from embit import bip39 from seedsigner.models.settings import SettingsConstants -spanish_wordlist = ["ábaco", "abdomen", "abeja", "abierto", "abogado", "abono", "aborto", "abrazo", "abrir", "abuelo", "abuso", "acabar", "academia", "acceso", "acción", "aceite", "acelga", "acento", "aceptar", "ácido", "aclarar", "acné", "acoger", "acoso", "activo", "acto", "actriz", "actuar", "acudir", "acuerdo", "acusar", "adicto", "admitir", "adoptar", "adorno", "aduana", "adulto", "aéreo", "afectar", "afición", "afinar", "afirmar", "ágil", "agitar", "agonía", "agosto", "agotar", "agregar", "agrio", "agua", "agudo", "águila", "aguja", "ahogo", "ahorro", "aire", "aislar", "ajedrez", "ajeno", "ajuste", "alacrán", "alambre", "alarma", "alba", "álbum", "alcalde", "aldea", "alegre", "alejar", "alerta", "aleta", "alfiler", "alga", "algodón", "aliado", "aliento", "alivio", "alma", "almeja", "almíbar", "altar", "alteza", "altivo", "alto", "altura", "alumno", "alzar", "amable", "amante", "amapola", "amargo", "amasar", "ámbar", "ámbito", "ameno", "amigo", "amistad", "amor", "amparo", "amplio", "ancho", "anciano", "ancla", "andar", "andén", "anemia", "ángulo", "anillo", "ánimo", "anís", "anotar", "antena", "antiguo", "antojo", "anual", "anular", "anuncio", "añadir", "añejo", "año", "apagar", "aparato", "apetito", "apio", "aplicar", "apodo", "aporte", "apoyo", "aprender", "aprobar", "apuesta", "apuro", "arado", "araña", "arar", "árbitro", "árbol", "arbusto", "archivo", "arco", "arder", "ardilla", "arduo", "área", "árido", "aries", "armonía", "arnés", "aroma", "arpa", "arpón", "arreglo", "arroz", "arruga", "arte", "artista", "asa", "asado", "asalto", "ascenso", "asegurar", "aseo", "asesor", "asiento", "asilo", "asistir", "asno", "asombro", "áspero", "astilla", "astro", "astuto", "asumir", "asunto", "atajo", "ataque", "atar", "atento", "ateo", "ático", "atleta", "átomo", "atraer", "atroz", "atún", "audaz", "audio", "auge", "aula", "aumento", "ausente", "autor", "aval", "avance", "avaro", "ave", "avellana", "avena", "avestruz", "avión", "aviso", "ayer", "ayuda", "ayuno", "azafrán", "azar", "azote", "azúcar", "azufre", "azul", "baba", "babor", "bache", "bahía", "baile", "bajar", "balanza", "balcón", "balde", "bambú", "banco", "banda", "baño", "barba", "barco", "barniz", "barro", "báscula", "bastón", "basura", "batalla", "batería", "batir", "batuta", "baúl", "bazar", "bebé", "bebida", "bello", "besar", "beso", "bestia", "bicho", "bien", "bingo", "blanco", "bloque", "blusa", "boa", "bobina", "bobo", "boca", "bocina", "boda", "bodega", "boina", "bola", "bolero", "bolsa", "bomba", "bondad", "bonito", "bono", "bonsái", "borde", "borrar", "bosque", "bote", "botín", "bóveda", "bozal", "bravo", "brazo", "brecha", "breve", "brillo", "brinco", "brisa", "broca", "broma", "bronce", "brote", "bruja", "brusco", "bruto", "buceo", "bucle", "bueno", "buey", "bufanda", "bufón", "búho", "buitre", "bulto", "burbuja", "burla", "burro", "buscar", "butaca", "buzón", "caballo", "cabeza", "cabina", "cabra", "cacao", "cadáver", "cadena", "caer", "café", "caída", "caimán", "caja", "cajón", "cal", "calamar", "calcio", "caldo", "calidad", "calle", "calma", "calor", "calvo", "cama", "cambio", "camello", "camino", "campo", "cáncer", "candil", "canela", "canguro", "canica", "canto", "caña", "cañón", "caoba", "caos", "capaz", "capitán", "capote", "captar", "capucha", "cara", "carbón", "cárcel", "careta", "carga", "cariño", "carne", "carpeta", "carro", "carta", "casa", "casco", "casero", "caspa", "castor", "catorce", "catre", "caudal", "causa", "cazo", "cebolla", "ceder", "cedro", "celda", "célebre", "celoso", "célula", "cemento", "ceniza", "centro", "cerca", "cerdo", "cereza", "cero", "cerrar", "certeza", "césped", "cetro", "chacal", "chaleco", "champú", "chancla", "chapa", "charla", "chico", "chiste", "chivo", "choque", "choza", "chuleta", "chupar", "ciclón", "ciego", "cielo", "cien", "cierto", "cifra", "cigarro", "cima", "cinco", "cine", "cinta", "ciprés", "circo", "ciruela", "cisne", "cita", "ciudad", "clamor", "clan", "claro", "clase", "clave", "cliente", "clima", "clínica", "cobre", "cocción", "cochino", "cocina", "coco", "código", "codo", "cofre", "coger", "cohete", "cojín", "cojo", "cola", "colcha", "colegio", "colgar", "colina", "collar", "colmo", "columna", "combate", "comer", "comida", "cómodo", "compra", "conde", "conejo", "conga", "conocer", "consejo", "contar", "copa", "copia", "corazón", "corbata", "corcho", "cordón", "corona", "correr", "coser", "cosmos", "costa", "cráneo", "cráter", "crear", "crecer", "creído", "crema", "cría", "crimen", "cripta", "crisis", "cromo", "crónica", "croqueta", "crudo", "cruz", "cuadro", "cuarto", "cuatro", "cubo", "cubrir", "cuchara", "cuello", "cuento", "cuerda", "cuesta", "cueva", "cuidar", "culebra", "culpa", "culto", "cumbre", "cumplir", "cuna", "cuneta", "cuota", "cupón", "cúpula", "curar", "curioso", "curso", "curva", "cutis", "dama", "danza", "dar", "dardo", "dátil", "deber", "débil", "década", "decir", "dedo", "defensa", "definir", "dejar", "delfín", "delgado", "delito", "demora", "denso", "dental", "deporte", "derecho", "derrota", "desayuno", "deseo", "desfile", "desnudo", "destino", "desvío", "detalle", "detener", "deuda", "día", "diablo", "diadema", "diamante", "diana", "diario", "dibujo", "dictar", "diente", "dieta", "diez", "difícil", "digno", "dilema", "diluir", "dinero", "directo", "dirigir", "disco", "diseño", "disfraz", "diva", "divino", "doble", "doce", "dolor", "domingo", "don", "donar", "dorado", "dormir", "dorso", "dos", "dosis", "dragón", "droga", "ducha", "duda", "duelo", "dueño", "dulce", "dúo", "duque", "durar", "dureza", "duro", "ébano", "ebrio", "echar", "eco", "ecuador", "edad", "edición", "edificio", "editor", "educar", "efecto", "eficaz", "eje", "ejemplo", "elefante", "elegir", "elemento", "elevar", "elipse", "élite", "elixir", "elogio", "eludir", "embudo", "emitir", "emoción", "empate", "empeño", "empleo", "empresa", "enano", "encargo", "enchufe", "encía", "enemigo", "enero", "enfado", "enfermo", "engaño", "enigma", "enlace", "enorme", "enredo", "ensayo", "enseñar", "entero", "entrar", "envase", "envío", "época", "equipo", "erizo", "escala", "escena", "escolar", "escribir", "escudo", "esencia", "esfera", "esfuerzo", "espada", "espejo", "espía", "esposa", "espuma", "esquí", "estar", "este", "estilo", "estufa", "etapa", "eterno", "ética", "etnia", "evadir", "evaluar", "evento", "evitar", "exacto", "examen", "exceso", "excusa", "exento", "exigir", "exilio", "existir", "éxito", "experto", "explicar", "exponer", "extremo", "fábrica", "fábula", "fachada", "fácil", "factor", "faena", "faja", "falda", "fallo", "falso", "faltar", "fama", "familia", "famoso", "faraón", "farmacia", "farol", "farsa", "fase", "fatiga", "fauna", "favor", "fax", "febrero", "fecha", "feliz", "feo", "feria", "feroz", "fértil", "fervor", "festín", "fiable", "fianza", "fiar", "fibra", "ficción", "ficha", "fideo", "fiebre", "fiel", "fiera", "fiesta", "figura", "fijar", "fijo", "fila", "filete", "filial", "filtro", "fin", "finca", "fingir", "finito", "firma", "flaco", "flauta", "flecha", "flor", "flota", "fluir", "flujo", "flúor", "fobia", "foca", "fogata", "fogón", "folio", "folleto", "fondo", "forma", "forro", "fortuna", "forzar", "fosa", "foto", "fracaso", "frágil", "franja", "frase", "fraude", "freír", "freno", "fresa", "frío", "frito", "fruta", "fuego", "fuente", "fuerza", "fuga", "fumar", "función", "funda", "furgón", "furia", "fusil", "fútbol", "futuro", "gacela", "gafas", "gaita", "gajo", "gala", "galería", "gallo", "gamba", "ganar", "gancho", "ganga", "ganso", "garaje", "garza", "gasolina", "gastar", "gato", "gavilán", "gemelo", "gemir", "gen", "género", "genio", "gente", "geranio", "gerente", "germen", "gesto", "gigante", "gimnasio", "girar", "giro", "glaciar", "globo", "gloria", "gol", "golfo", "goloso", "golpe", "goma", "gordo", "gorila", "gorra", "gota", "goteo", "gozar", "grada", "gráfico", "grano", "grasa", "gratis", "grave", "grieta", "grillo", "gripe", "gris", "grito", "grosor", "grúa", "grueso", "grumo", "grupo", "guante", "guapo", "guardia", "guerra", "guía", "guiño", "guion", "guiso", "guitarra", "gusano", "gustar", "haber", "hábil", "hablar", "hacer", "hacha", "hada", "hallar", "hamaca", "harina", "haz", "hazaña", "hebilla", "hebra", "hecho", "helado", "helio", "hembra", "herir", "hermano", "héroe", "hervir", "hielo", "hierro", "hígado", "higiene", "hijo", "himno", "historia", "hocico", "hogar", "hoguera", "hoja", "hombre", "hongo", "honor", "honra", "hora", "hormiga", "horno", "hostil", "hoyo", "hueco", "huelga", "huerta", "hueso", "huevo", "huida", "huir", "humano", "húmedo", "humilde", "humo", "hundir", "huracán", "hurto", "icono", "ideal", "idioma", "ídolo", "iglesia", "iglú", "igual", "ilegal", "ilusión", "imagen", "imán", "imitar", "impar", "imperio", "imponer", "impulso", "incapaz", "índice", "inerte", "infiel", "informe", "ingenio", "inicio", "inmenso", "inmune", "innato", "insecto", "instante", "interés", "íntimo", "intuir", "inútil", "invierno", "ira", "iris", "ironía", "isla", "islote", "jabalí", "jabón", "jamón", "jarabe", "jardín", "jarra", "jaula", "jazmín", "jefe", "jeringa", "jinete", "jornada", "joroba", "joven", "joya", "juerga", "jueves", "juez", "jugador", "jugo", "juguete", "juicio", "junco", "jungla", "junio", "juntar", "júpiter", "jurar", "justo", "juvenil", "juzgar", "kilo", "koala", "labio", "lacio", "lacra", "lado", "ladrón", "lagarto", "lágrima", "laguna", "laico", "lamer", "lámina", "lámpara", "lana", "lancha", "langosta", "lanza", "lápiz", "largo", "larva", "lástima", "lata", "látex", "latir", "laurel", "lavar", "lazo", "leal", "lección", "leche", "lector", "leer", "legión", "legumbre", "lejano", "lengua", "lento", "leña", "león", "leopardo", "lesión", "letal", "letra", "leve", "leyenda", "libertad", "libro", "licor", "líder", "lidiar", "lienzo", "liga", "ligero", "lima", "límite", "limón", "limpio", "lince", "lindo", "línea", "lingote", "lino", "linterna", "líquido", "liso", "lista", "litera", "litio", "litro", "llaga", "llama", "llanto", "llave", "llegar", "llenar", "llevar", "llorar", "llover", "lluvia", "lobo", "loción", "loco", "locura", "lógica", "logro", "lombriz", "lomo", "lonja", "lote", "lucha", "lucir", "lugar", "lujo", "luna", "lunes", "lupa", "lustro", "luto", "luz", "maceta", "macho", "madera", "madre", "maduro", "maestro", "mafia", "magia", "mago", "maíz", "maldad", "maleta", "malla", "malo", "mamá", "mambo", "mamut", "manco", "mando", "manejar", "manga", "maniquí", "manjar", "mano", "manso", "manta", "mañana", "mapa", "máquina", "mar", "marco", "marea", "marfil", "margen", "marido", "mármol", "marrón", "martes", "marzo", "masa", "máscara", "masivo", "matar", "materia", "matiz", "matriz", "máximo", "mayor", "mazorca", "mecha", "medalla", "medio", "médula", "mejilla", "mejor", "melena", "melón", "memoria", "menor", "mensaje", "mente", "menú", "mercado", "merengue", "mérito", "mes", "mesón", "meta", "meter", "método", "metro", "mezcla", "miedo", "miel", "miembro", "miga", "mil", "milagro", "militar", "millón", "mimo", "mina", "minero", "mínimo", "minuto", "miope", "mirar", "misa", "miseria", "misil", "mismo", "mitad", "mito", "mochila", "moción", "moda", "modelo", "moho", "mojar", "molde", "moler", "molino", "momento", "momia", "monarca", "moneda", "monja", "monto", "moño", "morada", "morder", "moreno", "morir", "morro", "morsa", "mortal", "mosca", "mostrar", "motivo", "mover", "móvil", "mozo", "mucho", "mudar", "mueble", "muela", "muerte", "muestra", "mugre", "mujer", "mula", "muleta", "multa", "mundo", "muñeca", "mural", "muro", "músculo", "museo", "musgo", "música", "muslo", "nácar", "nación", "nadar", "naipe", "naranja", "nariz", "narrar", "nasal", "natal", "nativo", "natural", "náusea", "naval", "nave", "navidad", "necio", "néctar", "negar", "negocio", "negro", "neón", "nervio", "neto", "neutro", "nevar", "nevera", "nicho", "nido", "niebla", "nieto", "niñez", "niño", "nítido", "nivel", "nobleza", "noche", "nómina", "noria", "norma", "norte", "nota", "noticia", "novato", "novela", "novio", "nube", "nuca", "núcleo", "nudillo", "nudo", "nuera", "nueve", "nuez", "nulo", "número", "nutria", "oasis", "obeso", "obispo", "objeto", "obra", "obrero", "observar", "obtener", "obvio", "oca", "ocaso", "océano", "ochenta", "ocho", "ocio", "ocre", "octavo", "octubre", "oculto", "ocupar", "ocurrir", "odiar", "odio", "odisea", "oeste", "ofensa", "oferta", "oficio", "ofrecer", "ogro", "oído", "oír", "ojo", "ola", "oleada", "olfato", "olivo", "olla", "olmo", "olor", "olvido", "ombligo", "onda", "onza", "opaco", "opción", "ópera", "opinar", "oponer", "optar", "óptica", "opuesto", "oración", "orador", "oral", "órbita", "orca", "orden", "oreja", "órgano", "orgía", "orgullo", "oriente", "origen", "orilla", "oro", "orquesta", "oruga", "osadía", "oscuro", "osezno", "oso", "ostra", "otoño", "otro", "oveja", "óvulo", "óxido", "oxígeno", "oyente", "ozono", "pacto", "padre", "paella", "página", "pago", "país", "pájaro", "palabra", "palco", "paleta", "pálido", "palma", "paloma", "palpar", "pan", "panal", "pánico", "pantera", "pañuelo", "papá", "papel", "papilla", "paquete", "parar", "parcela", "pared", "parir", "paro", "párpado", "parque", "párrafo", "parte", "pasar", "paseo", "pasión", "paso", "pasta", "pata", "patio", "patria", "pausa", "pauta", "pavo", "payaso", "peatón", "pecado", "pecera", "pecho", "pedal", "pedir", "pegar", "peine", "pelar", "peldaño", "pelea", "peligro", "pellejo", "pelo", "peluca", "pena", "pensar", "peñón", "peón", "peor", "pepino", "pequeño", "pera", "percha", "perder", "pereza", "perfil", "perico", "perla", "permiso", "perro", "persona", "pesa", "pesca", "pésimo", "pestaña", "pétalo", "petróleo", "pez", "pezuña", "picar", "pichón", "pie", "piedra", "pierna", "pieza", "pijama", "pilar", "piloto", "pimienta", "pino", "pintor", "pinza", "piña", "piojo", "pipa", "pirata", "pisar", "piscina", "piso", "pista", "pitón", "pizca", "placa", "plan", "plata", "playa", "plaza", "pleito", "pleno", "plomo", "pluma", "plural", "pobre", "poco", "poder", "podio", "poema", "poesía", "poeta", "polen", "policía", "pollo", "polvo", "pomada", "pomelo", "pomo", "pompa", "poner", "porción", "portal", "posada", "poseer", "posible", "poste", "potencia", "potro", "pozo", "prado", "precoz", "pregunta", "premio", "prensa", "preso", "previo", "primo", "príncipe", "prisión", "privar", "proa", "probar", "proceso", "producto", "proeza", "profesor", "programa", "prole", "promesa", "pronto", "propio", "próximo", "prueba", "público", "puchero", "pudor", "pueblo", "puerta", "puesto", "pulga", "pulir", "pulmón", "pulpo", "pulso", "puma", "punto", "puñal", "puño", "pupa", "pupila", "puré", "quedar", "queja", "quemar", "querer", "queso", "quieto", "química", "quince", "quitar", "rábano", "rabia", "rabo", "ración", "radical", "raíz", "rama", "rampa", "rancho", "rango", "rapaz", "rápido", "rapto", "rasgo", "raspa", "rato", "rayo", "raza", "razón", "reacción", "realidad", "rebaño", "rebote", "recaer", "receta", "rechazo", "recoger", "recreo", "recto", "recurso", "red", "redondo", "reducir", "reflejo", "reforma", "refrán", "refugio", "regalo", "regir", "regla", "regreso", "rehén", "reino", "reír", "reja", "relato", "relevo", "relieve", "relleno", "reloj", "remar", "remedio", "remo", "rencor", "rendir", "renta", "reparto", "repetir", "reposo", "reptil", "res", "rescate", "resina", "respeto", "resto", "resumen", "retiro", "retorno", "retrato", "reunir", "revés", "revista", "rey", "rezar", "rico", "riego", "rienda", "riesgo", "rifa", "rígido", "rigor", "rincón", "riñón", "río", "riqueza", "risa", "ritmo", "rito", "rizo", "roble", "roce", "rociar", "rodar", "rodeo", "rodilla", "roer", "rojizo", "rojo", "romero", "romper", "ron", "ronco", "ronda", "ropa", "ropero", "rosa", "rosca", "rostro", "rotar", "rubí", "rubor", "rudo", "rueda", "rugir", "ruido", "ruina", "ruleta", "rulo", "rumbo", "rumor", "ruptura", "ruta", "rutina", "sábado", "saber", "sabio", "sable", "sacar", "sagaz", "sagrado", "sala", "saldo", "salero", "salir", "salmón", "salón", "salsa", "salto", "salud", "salvar", "samba", "sanción", "sandía", "sanear", "sangre", "sanidad", "sano", "santo", "sapo", "saque", "sardina", "sartén", "sastre", "satán", "sauna", "saxofón", "sección", "seco", "secreto", "secta", "sed", "seguir", "seis", "sello", "selva", "semana", "semilla", "senda", "sensor", "señal", "señor", "separar", "sepia", "sequía", "ser", "serie", "sermón", "servir", "sesenta", "sesión", "seta", "setenta", "severo", "sexo", "sexto", "sidra", "siesta", "siete", "siglo", "signo", "sílaba", "silbar", "silencio", "silla", "símbolo", "simio", "sirena", "sistema", "sitio", "situar", "sobre", "socio", "sodio", "sol", "solapa", "soldado", "soledad", "sólido", "soltar", "solución", "sombra", "sondeo", "sonido", "sonoro", "sonrisa", "sopa", "soplar", "soporte", "sordo", "sorpresa", "sorteo", "sostén", "sótano", "suave", "subir", "suceso", "sudor", "suegra", "suelo", "sueño", "suerte", "sufrir", "sujeto", "sultán", "sumar", "superar", "suplir", "suponer", "supremo", "sur", "surco", "sureño", "surgir", "susto", "sutil", "tabaco", "tabique", "tabla", "tabú", "taco", "tacto", "tajo", "talar", "talco", "talento", "talla", "talón", "tamaño", "tambor", "tango", "tanque", "tapa", "tapete", "tapia", "tapón", "taquilla", "tarde", "tarea", "tarifa", "tarjeta", "tarot", "tarro", "tarta", "tatuaje", "tauro", "taza", "tazón", "teatro", "techo", "tecla", "técnica", "tejado", "tejer", "tejido", "tela", "teléfono", "tema", "temor", "templo", "tenaz", "tender", "tener", "tenis", "tenso", "teoría", "terapia", "terco", "término", "ternura", "terror", "tesis", "tesoro", "testigo", "tetera", "texto", "tez", "tibio", "tiburón", "tiempo", "tienda", "tierra", "tieso", "tigre", "tijera", "tilde", "timbre", "tímido", "timo", "tinta", "tío", "típico", "tipo", "tira", "tirón", "titán", "títere", "título", "tiza", "toalla", "tobillo", "tocar", "tocino", "todo", "toga", "toldo", "tomar", "tono", "tonto", "topar", "tope", "toque", "tórax", "torero", "tormenta", "torneo", "toro", "torpedo", "torre", "torso", "tortuga", "tos", "tosco", "toser", "tóxico", "trabajo", "tractor", "traer", "tráfico", "trago", "traje", "tramo", "trance", "trato", "trauma", "trazar", "trébol", "tregua", "treinta", "tren", "trepar", "tres", "tribu", "trigo", "tripa", "triste", "triunfo", "trofeo", "trompa", "tronco", "tropa", "trote", "trozo", "truco", "trueno", "trufa", "tubería", "tubo", "tuerto", "tumba", "tumor", "túnel", "túnica", "turbina", "turismo", "turno", "tutor", "ubicar", "úlcera", "umbral", "unidad", "unir", "universo", "uno", "untar", "uña", "urbano", "urbe", "urgente", "urna", "usar", "usuario", "útil", "utopía", "uva", "vaca", "vacío", "vacuna", "vagar", "vago", "vaina", "vajilla", "vale", "válido", "valle", "valor", "válvula", "vampiro", "vara", "variar", "varón", "vaso", "vecino", "vector", "vehículo", "veinte", "vejez", "vela", "velero", "veloz", "vena", "vencer", "venda", "veneno", "vengar", "venir", "venta", "venus", "ver", "verano", "verbo", "verde", "vereda", "verja", "verso", "verter", "vía", "viaje", "vibrar", "vicio", "víctima", "vida", "vídeo", "vidrio", "viejo", "viernes", "vigor", "vil", "villa", "vinagre", "vino", "viñedo", "violín", "viral", "virgo", "virtud", "visor", "víspera", "vista", "vitamina", "viudo", "vivaz", "vivero", "vivir", "vivo", "volcán", "volumen", "volver", "voraz", "votar", "voto", "voz", "vuelo", "vulgar", "yacer", "yate", "yegua", "yema", "yerno", "yeso", "yodo", "yoga", "yogur", "zafiro", "zanja", "zapato", "zarza", "zona", "zorro", "zumo", "zurdo"] +# TODO: Re-enable once multi-language bip-39 wordlists are supported +@pytest.mark.skip def test_seed(): - seed = Seed(mnemonic="obscure bone gas open exotic abuse virus bunker shuffle nasty ship dash") + seed = Seed(mnemonic="obscure bone gas open exotic abuse virus bunker shuffle nasty ship dash".split()) assert seed.seed_bytes == b'q\xb3\xd1i\x0c\x9b\x9b\xdf\xa7\xd9\xd97H\xa8,\xa7\xd9>\xeck\xc2\xf5ND?, \x88-\x07\x9aa\xc5\xee\xb7\xbf\xc4x\xd6\x07 X\xb6}?M\xaa\x05\xa6\xa7(>\xbf\x03\xb0\x9d\xef\xed":\xdf\x88w7' @@ -18,7 +19,7 @@ def test_seed(): assert seed.passphrase == "" # TODO: Not yet supported in new implementation - seed.set_wordlist_language_code(SettingsConstants.WORDLIST_LANGUAGE__SPANISH) + seed.set_wordlist_language_code("es") assert seed.mnemonic_str == "natural ayuda futuro nivel espejo abuelo vago bien repetir moreno relevo conga" @@ -29,7 +30,7 @@ def test_seed(): assert seed.mnemonic_str == "height demise useless trap grow lion found off key clown transfer enroll" # TODO: Not yet supported in new implementation - seed.set_wordlist_language_code(SettingsConstants.WORDLIST_LANGUAGE__SPANISH) + seed.set_wordlist_language_code("es") assert seed.mnemonic_str == "hebilla cría truco tigre gris llenar folio negocio laico casa tieso eludir" diff --git a/tests/test_seedqr.py b/tests/test_seedqr.py index b7668bee..7e2d6385 100644 --- a/tests/test_seedqr.py +++ b/tests/test_seedqr.py @@ -9,6 +9,7 @@ from seedsigner.models.qr_type import QRType from seedsigner.models.settings import SettingsConstants + def run_encode_decode_test(entropy: bytes, mnemonic_length, qr_type): """ Helper method to re-run multiple variations of the same encode/decode test """ print(entropy) @@ -16,7 +17,7 @@ def run_encode_decode_test(entropy: bytes, mnemonic_length, qr_type): print(seed_phrase) assert len(seed_phrase) == mnemonic_length - e = EncodeQR(seed_phrase=seed_phrase, qr_type=qr_type, wordlist=bip39.WORDLIST) + e = EncodeQR(seed_phrase=seed_phrase, qr_type=qr_type) data = e.next_part() print(data) @@ -28,7 +29,7 @@ def run_encode_decode_test(entropy: bytes, mnemonic_length, qr_type): border=3 ) - decoder = DecodeQR(wordlist_language_code=SettingsConstants.LANGUAGE__ENGLISH) + decoder = DecodeQR() status = decoder.add_image(image) assert status == DecodeQRStatus.COMPLETE