mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Adds Settings option to enable CompactSeedQR; more test scenarios
Also misc cleanup, simplifications (f-strings in `settings_tools_view.py`.
This commit is contained in:
@@ -12,4 +12,5 @@ camera_rotation = 0
|
||||
network = main
|
||||
software = Prompt
|
||||
qr_density = 2
|
||||
custom_derivation = m/0/0
|
||||
custom_derivation = m/0/0
|
||||
compact_seedqr_enabled = False
|
||||
@@ -159,6 +159,8 @@ class Controller(Singleton):
|
||||
ret_val = self.show_persistent_settings_tool()
|
||||
elif ret_val == Path.CAMERA_ROTATION:
|
||||
ret_val = self.show_camera_rotation_tool()
|
||||
elif ret_val == Path.COMPACT_SEEDQR_ENABLED:
|
||||
ret_val = self.show_compact_seedqr_enabled()
|
||||
elif ret_val == Path.DONATE:
|
||||
ret_val = self.show_donate_tool()
|
||||
elif ret_val == Path.RESET:
|
||||
@@ -1111,6 +1113,14 @@ class Controller(Singleton):
|
||||
|
||||
return Path.SETTINGS_SUB_MENU ### Show Donate Screen and QR
|
||||
|
||||
|
||||
def show_compact_seedqr_enabled(self):
|
||||
r = self.settings_tools_view.display_compact_seedqr_enabled()
|
||||
if r is not None:
|
||||
self.settings.compact_seedqr_enabled = r
|
||||
|
||||
return Path.SETTINGS_SUB_MENU ### Show Donate Screen and QR
|
||||
|
||||
def show_donate_tool(self):
|
||||
self.settings_tools_view.display_donate_info_screen()
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class Path:
|
||||
QR_DENSITY_SETTING = 65
|
||||
PERSISTENT_SETTINGS = 67
|
||||
CAMERA_ROTATION = 69
|
||||
COMPACT_SEEDQR_ENABLED = 70
|
||||
RESET = 68
|
||||
|
||||
# Seed Slots
|
||||
|
||||
@@ -248,9 +248,6 @@ class CompactSeedQR(SeedQR):
|
||||
for i in range(0, math.ceil(len(binary_str) / 8)):
|
||||
# int conversion reads byte data as a string prefixed with '0b'
|
||||
as_bytes.append(int('0b' + binary_str[i*8:(i+1)*8], 2))
|
||||
|
||||
print(f"num bytes: {len(as_bytes)}")
|
||||
print(as_bytes)
|
||||
|
||||
# Must return data as `bytes` for `qrcode` to properly recognize it as byte data
|
||||
return bytes(as_bytes)
|
||||
|
||||
@@ -34,7 +34,8 @@ class Settings(Singleton):
|
||||
'network': "main",
|
||||
'software': "Specter Desktop",
|
||||
'qr_density': EncodeQRDensity.MEDIUM,
|
||||
'custom_derivation': 'm/0/0'
|
||||
'custom_derivation': 'm/0/0',
|
||||
'compact_seedqr_enabled': False,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,12 +52,13 @@ class Settings(Singleton):
|
||||
self._data["system"]["debug"] = config.getboolean("system", "debug")
|
||||
self._data["system"]["default_language"] = config["system"]["default_language"]
|
||||
self._data["display"]["text_color"] = config["display"]["text_color"]
|
||||
self.qr_background_color = config["display"]["qr_background_color"]
|
||||
self._data["display"]["camera_rotation"] = int(config["display"]["camera_rotation"])
|
||||
self.network = config["wallet"]["network"]
|
||||
self.software = config["wallet"]["software"]
|
||||
self.qr_density = int(config["wallet"]["qr_density"])
|
||||
self.custom_derivation = config["wallet"]["custom_derivation"]
|
||||
self.qr_background_color = config["display"]["qr_background_color"]
|
||||
self.compact_seedqr_enabled = config.getboolean("wallet", "compact_seedqr_enabled")
|
||||
|
||||
### persistent settings handling
|
||||
|
||||
@@ -225,7 +227,17 @@ class Settings(Singleton):
|
||||
def custom_derivation(self, value):
|
||||
# TODO: parse and validate custom derivation path
|
||||
self._data["wallet"]["custom_derivation"] = value
|
||||
|
||||
self.__writeConfig()
|
||||
|
||||
@property
|
||||
def compact_seedqr_enabled(self):
|
||||
return self._data["wallet"]["compact_seedqr_enabled"]
|
||||
|
||||
@compact_seedqr_enabled.setter
|
||||
def compact_seedqr_enabled(self, value):
|
||||
self._data["wallet"]["compact_seedqr_enabled"] = value
|
||||
self.__writeConfig()
|
||||
|
||||
@staticmethod
|
||||
def calc_derivation(network, wallet_type, script_type):
|
||||
if network == "main":
|
||||
|
||||
@@ -124,13 +124,20 @@ class MenuView(View):
|
||||
### Settings Menu
|
||||
|
||||
def display_settings_menu(self) -> int:
|
||||
lines = ["... [ Return to Main ]", "Wallet: <wallet>", "Network: <network>", "QR Density: <density>", "Input / Output Tests", "Persistent Settings: <persistent>", "Camera Rotation", "Version Info", "Donate to SeedSigner", "Reset SeedSigner"]
|
||||
lines = [
|
||||
"... [ Return to Main ]",
|
||||
f"Wallet: {Settings.get_instance().software}",
|
||||
f"Network: {Settings.get_instance().network}",
|
||||
f"QR Density: {Settings.get_instance().qr_density_name}",
|
||||
"Input / Output Tests",
|
||||
f"Persistent Settings: {Settings.get_instance().persistent_display}",
|
||||
f"Camera Rotation: {Settings.get_instance().camera_rotation}°",
|
||||
f"Compact SeedQR: {'Enabled' if Settings.get_instance().compact_seedqr_enabled else 'Disabled'}",
|
||||
"Version Info",
|
||||
"Donate to SeedSigner",
|
||||
"Reset SeedSigner"
|
||||
]
|
||||
input = 0
|
||||
|
||||
lines[1] = lines[1].replace("<wallet>", Settings.get_instance().software)
|
||||
lines[2] = lines[2].replace("<network>", Settings.get_instance().network)
|
||||
lines[3] = lines[3].replace("<density>", Settings.get_instance().qr_density_name)
|
||||
lines[5] = lines[5].replace("<persistent>", Settings.get_instance().persistent_display)
|
||||
|
||||
# Draw Menu
|
||||
self.selected_menu_num = 1
|
||||
@@ -159,10 +166,12 @@ class MenuView(View):
|
||||
elif self.selected_menu_num == 7:
|
||||
return Path.CAMERA_ROTATION
|
||||
elif self.selected_menu_num == 8:
|
||||
return Path.VERSION_INFO
|
||||
return Path.COMPACT_SEEDQR_ENABLED
|
||||
elif self.selected_menu_num == 9:
|
||||
return Path.DONATE
|
||||
return Path.VERSION_INFO
|
||||
elif self.selected_menu_num == 10:
|
||||
return Path.DONATE
|
||||
elif self.selected_menu_num == 11:
|
||||
return Path.RESET
|
||||
raise Exception("Unhandled case")
|
||||
|
||||
|
||||
@@ -967,7 +967,10 @@ class SeedToolsView(View):
|
||||
|
||||
elif show_qr_option and ret_val == B.KEY_RIGHT:
|
||||
# Show the resulting seed as a transcribable QR code
|
||||
self.display_seed_qr_options(seed_phrase)
|
||||
if self.controller.settings.compact_seedqr_enabled:
|
||||
self.display_seed_qr_options(seed_phrase)
|
||||
else:
|
||||
self.seed_phrase_as_qr(seed_phrase)
|
||||
|
||||
# Signal success to move forward
|
||||
return True
|
||||
@@ -994,7 +997,10 @@ class SeedToolsView(View):
|
||||
|
||||
elif show_qr_option and ret_val == B.KEY_RIGHT:
|
||||
# Show the resulting seed as a transcribable QR code
|
||||
self.display_seed_qr_options(seed_phrase)
|
||||
if self.controller.settings.compact_seedqr_enabled:
|
||||
self.display_seed_qr_options(seed_phrase)
|
||||
else:
|
||||
self.seed_phrase_as_qr(seed_phrase)
|
||||
|
||||
# Signal success to move forward
|
||||
return True
|
||||
@@ -1025,7 +1031,7 @@ class SeedToolsView(View):
|
||||
return None
|
||||
|
||||
|
||||
def seed_phrase_as_qr(self, seed_phrase, is_compact_seedqr=True):
|
||||
def seed_phrase_as_qr(self, seed_phrase, is_compact_seedqr=False):
|
||||
if is_compact_seedqr:
|
||||
e = EncodeQR(seed_phrase=seed_phrase, qr_type=QRType.COMPACTSEEDQR, wordlist=self.controller.settings.wordlist)
|
||||
else:
|
||||
|
||||
@@ -64,7 +64,6 @@ class SettingsToolsView(View):
|
||||
return None
|
||||
|
||||
def display_persistent_settings(self) -> bool:
|
||||
|
||||
lines = ["... [ Return to Settings ]"]
|
||||
lines.append("Yes")
|
||||
lines.append("No")
|
||||
@@ -82,10 +81,10 @@ class SettingsToolsView(View):
|
||||
|
||||
def display_camera_rotation(self) -> int:
|
||||
lines = ["... [ Return to Settings ]"]
|
||||
lines.append("0 (default)")
|
||||
lines.append("90")
|
||||
lines.append("180")
|
||||
lines.append("270")
|
||||
lines.append("0° (default)")
|
||||
lines.append("90°")
|
||||
lines.append("180°")
|
||||
lines.append("270°")
|
||||
|
||||
r = self.controller.menu_view.display_generic_selection_menu(lines, "Camera Rotation")
|
||||
if r == 1:
|
||||
@@ -123,7 +122,6 @@ class SettingsToolsView(View):
|
||||
###
|
||||
### Custom Derivation Path
|
||||
###
|
||||
|
||||
def draw_derivation_keyboard_entry(self, existing_derivation = "m/"):
|
||||
def render_right_panel():
|
||||
row_height = 28
|
||||
@@ -273,4 +271,20 @@ class SettingsToolsView(View):
|
||||
# Render the text entry display and cursor block
|
||||
text_entry_display.render(self.derivation)
|
||||
|
||||
View.DispShowImage()
|
||||
View.DispShowImage()
|
||||
|
||||
|
||||
def display_compact_seedqr_enabled(self) -> bool:
|
||||
lines = ["... [ Return to Settings ]"]
|
||||
lines.append("Enable")
|
||||
lines.append("Disable")
|
||||
|
||||
r = self.controller.menu_view.display_generic_selection_menu(lines, "Compact SeedQR")
|
||||
if r == 1:
|
||||
return None
|
||||
elif r == 2:
|
||||
return True
|
||||
elif r == 3:
|
||||
return False
|
||||
else:
|
||||
return None
|
||||
|
||||
+2
-1
@@ -12,4 +12,5 @@ camera_rotation = 0
|
||||
network = main
|
||||
software = Prompt
|
||||
qr_density = 2
|
||||
custom_derivation = m/0/0
|
||||
custom_derivation = m/0/0
|
||||
compact_seedqr_enabled = False
|
||||
@@ -77,6 +77,14 @@ def test_compact_seedqr_handles_null_bytes():
|
||||
entropy = os.urandom(31) + b'\x00'
|
||||
run_encode_decode_test(entropy, mnemonic_length=24, qr_type=QRType.COMPACTSEEDQR)
|
||||
|
||||
# 24-word seed, multiple null bytes
|
||||
entropy = os.urandom(5) + b'\x00' + os.urandom(5) + b'\x00' + os.urandom(20)
|
||||
run_encode_decode_test(entropy, mnemonic_length=24, qr_type=QRType.COMPACTSEEDQR)
|
||||
|
||||
# 24-word seed, multiple null bytes in a row
|
||||
entropy = os.urandom(10) + b'\x00\x00' + os.urandom(20)
|
||||
run_encode_decode_test(entropy, mnemonic_length=24, qr_type=QRType.COMPACTSEEDQR)
|
||||
|
||||
# 12-word seed, null bytes at the beginning
|
||||
entropy = b'\x00' + os.urandom(15)
|
||||
run_encode_decode_test(entropy, mnemonic_length=12, qr_type=QRType.COMPACTSEEDQR)
|
||||
@@ -88,3 +96,11 @@ def test_compact_seedqr_handles_null_bytes():
|
||||
# 12-word seed, null bytes at the end
|
||||
entropy = os.urandom(15) + b'\x00'
|
||||
run_encode_decode_test(entropy, mnemonic_length=12, qr_type=QRType.COMPACTSEEDQR)
|
||||
|
||||
# 12-word seed, multiple null bytes
|
||||
entropy = os.urandom(5) + b'\x00' + os.urandom(5) + b'\x00' + os.urandom(4)
|
||||
run_encode_decode_test(entropy, mnemonic_length=12, qr_type=QRType.COMPACTSEEDQR)
|
||||
|
||||
# 12-word seed, multiple null bytes in a row
|
||||
entropy = os.urandom(10) + b'\x00\x00' + os.urandom(4)
|
||||
run_encode_decode_test(entropy, mnemonic_length=12, qr_type=QRType.COMPACTSEEDQR)
|
||||
|
||||
Reference in New Issue
Block a user