Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions src/seedsigner/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,8 @@ def storage(self):
return self._storage


def get_seed(self, seed_num: int) -> Seed:
if seed_num < len(self.storage.seeds):
return self.storage.seeds[seed_num]
else:
raise Exception(f"There is no seed_num {seed_num}; only {len(self.storage.seeds)} in memory.")


def discard_seed(self, seed_num: int):
if seed_num < len(self.storage.seeds):
del self.storage.seeds[seed_num]
else:
raise Exception(f"There is no seed_num {seed_num}; only {len(self.storage.seeds)} in memory.")
def discard_seed(self, seed: Seed):
self.storage.seeds.remove(seed)


def pop_prev_from_back_stack(self):
Expand Down
14 changes: 6 additions & 8 deletions src/seedsigner/models/seed_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ def get_pending_seed(self) -> Seed:
return self.pending_seed


def finalize_pending_seed(self) -> int:
# Finally store the pending seed and return its index
if self.pending_seed in self.seeds:
index = self.seeds.index(self.pending_seed)
else:
self.seeds.append(self.pending_seed)
index = len(self.seeds) - 1
def finalize_pending_seed(self) -> Seed:
# Store the pending seed and return it
seed = self.pending_seed
if seed not in self.seeds:
self.seeds.append(seed)
self.pending_seed = None
return index
return seed


def clear_pending_seed(self):
Expand Down
321 changes: 151 additions & 170 deletions src/seedsigner/views/seed_views.py

Large diffs are not rendered by default.

34 changes: 16 additions & 18 deletions src/seedsigner/views/tools_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def run(self):
self.loading_screen.stop()

# Cannot return BACK to this View
return Destination(SeedWordsWarningView, view_args={"seed_num": None}, clear_history=True)
return Destination(SeedWordsWarningView, view_args={"seed": None}, clear_history=True)



Expand Down Expand Up @@ -256,7 +256,7 @@ def run(self):
self.controller.storage.set_pending_seed(seed)

# Cannot return BACK to this View
return Destination(SeedWordsWarningView, view_args={"seed_num": None}, clear_history=True)
return Destination(SeedWordsWarningView, view_args={"seed": None}, clear_history=True)



Expand Down Expand Up @@ -508,11 +508,11 @@ def run(self):
self.controller.resume_main_flow = Controller.FLOW__ADDRESS_EXPLORER

if len(seeds) > 0 and selected_menu_num < len(seeds):
# User selected one of the n seeds
selected_seed = seeds[selected_menu_num]
return Destination(
SeedExportXpubScriptTypeView,
view_args=dict(
seed_num=selected_menu_num,
seed=selected_seed,
sig_type=SettingsConstants.SINGLE_SIG,
)
)
Expand Down Expand Up @@ -544,32 +544,30 @@ class ToolsAddressExplorerAddressTypeView(View):
CHANGE = ButtonOption("Change addresses")


def __init__(self, seed_num: int = None, script_type: str = None, custom_derivation: str = None):
def __init__(self, seed: Seed = None, script_type: str = None, custom_derivation: str = None):
"""
If the explorer source is a seed, `seed_num` and `script_type` must be
If the explorer source is a seed, `seed` and `script_type` must be
specified. `custom_derivation` can be specified as needed.

If the source is a multisig or single sig wallet descriptor, `seed_num`,
If the source is a multisig or single sig wallet descriptor, `seed`,
`script_type`, and `custom_derivation` should be `None`.
"""
super().__init__()
self.seed_num = seed_num
self.seed = seed
self.script_type = script_type
self.custom_derivation = custom_derivation

network = self.settings.get_value(SettingsConstants.SETTING__NETWORK)
self.network = self.settings.get_value(SettingsConstants.SETTING__NETWORK)

# Store everything in the Controller's `address_explorer_data` so we don't have
# to keep passing vals around from View to View and recalculating.
data = dict(
seed_num=seed_num,
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK),
embit_network=SettingsConstants.map_network_to_embit(network),
seed=self.seed,
network=self.network,
embit_network=SettingsConstants.map_network_to_embit(self.network),
script_type=script_type,
)
if self.seed_num is not None:
self.seed = self.controller.storage.seeds[seed_num]
data["seed_num"] = self.seed
if self.seed is not None:
seed_derivation_override = self.seed.derivation_override(sig_type=SettingsConstants.SINGLE_SIG)

if self.script_type == SettingsConstants.CUSTOM_DERIVATION:
Expand All @@ -579,13 +577,13 @@ def __init__(self, seed_num: int = None, script_type: str = None, custom_derivat
else:
from seedsigner.helpers import embit_utils
derivation_path = embit_utils.get_standard_derivation_path(
network=self.settings.get_value(SettingsConstants.SETTING__NETWORK),
network=self.network,
wallet_type=SettingsConstants.SINGLE_SIG,
script_type=self.script_type,
)

data["derivation_path"] = derivation_path
data["xpub"] = self.seed.get_xpub(derivation_path, network=network)
data["xpub"] = self.seed.get_xpub(derivation_path, network=self.network)

else:
data["wallet_descriptor"] = self.controller.multisig_wallet_descriptor
Expand All @@ -609,7 +607,7 @@ def run(self):
selected_menu_num = self.run_screen(
ToolsAddressExplorerAddressTypeScreen,
button_data=button_data,
fingerprint=self.seed.get_fingerprint() if self.seed_num is not None else None,
fingerprint=None if self.seed is None else self.seed.get_fingerprint(self.network),
wallet_descriptor_display_name=wallet_descriptor_display_name,
script_type=script_type,
custom_derivation_path=self.custom_derivation,
Expand Down
72 changes: 36 additions & 36 deletions tests/screenshot_generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def setup_screenshots(locale: str) -> dict[str, list[ScreenshotConfig]]:
# Message signing data
derivation_path = "m/84h/0h/0h/0/0"
controller.sign_message_data = {
"seed_num": 0,
"seed": seed_12,
"derivation_path": derivation_path,
"message": "I attest that I control this bitcoin address blah blah blah",
"addr_format": embit_utils.parse_derivation_path(derivation_path)
Expand Down Expand Up @@ -349,51 +349,51 @@ def mock_psbt_with_op_return_raw_bytes_loaded():
ScreenshotConfig(seed_views.SeedAddPassphraseExitDialogView),
ScreenshotConfig(seed_views.SeedReviewPassphraseView),

ScreenshotConfig(seed_views.SeedOptionsView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedBackupView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedExportXpubSigTypeView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedExportXpubScriptTypeView, dict(seed_num=0, sig_type="msig")),
ScreenshotConfig(seed_views.SeedExportXpubCustomDerivationView, dict(seed_num=0, sig_type="ss", script_type="")),
ScreenshotConfig(seed_views.SeedExportXpubQRFormatView, dict(seed_num=0, sig_type="ss", script_type="nat")),
ScreenshotConfig(seed_views.SeedExportXpubWarningView, dict(seed_num=0, sig_type="msig", script_type="nes", xpub_qr_format="urca", custom_derivation="")),
ScreenshotConfig(seed_views.SeedExportXpubDetailsView, dict(seed_num=0, sig_type="ss", script_type="nat", xpub_qr_format="urca", custom_derivation="")),
ScreenshotConfig(SeedExportXpubQR_ScreenBrightnessView, dict(seed_num=0, xpub_qr_format="urca", derivation_path="m/84'/0'/0'")),

ScreenshotConfig(seed_views.SeedWordsWarningView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedWordsView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedWordsView, dict(seed_num=0, page_index=2), screenshot_name="SeedWordsView_2"),
ScreenshotConfig(seed_views.SeedBIP85SelectNumWordsView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedBIP85SelectChildIndexView, dict(seed_num=0, num_words=24)),
ScreenshotConfig(seed_views.SeedBIP85InvalidChildIndexView, dict(seed_num=0, num_words=12)),
ScreenshotConfig(seed_views.SeedWordsBackupTestPromptView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedWordsBackupTestView, dict(seed_num=0, rand_seed=6102)),
ScreenshotConfig(seed_views.SeedWordsBackupTestMistakeView, dict(seed_num=0, cur_index=7, wrong_word="satoshi")),
ScreenshotConfig(seed_views.SeedWordsBackupTestSuccessView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRFormatView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWarningView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=21), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Standard"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__SEEDQR, num_modules=29), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Standard"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, initial_zone_x=1, initial_zone_y=1), screenshot_name="SeedTranscribeSeedQRZoomedInView_12_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, initial_zone_x=2, initial_zone_y=2), screenshot_name="SeedTranscribeSeedQRZoomedInView_12_Standard"),

ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmQRPromptView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedOptionsView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedBackupView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedExportXpubSigTypeView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedExportXpubScriptTypeView, dict(seed=seed_12, sig_type="msig")),
ScreenshotConfig(seed_views.SeedExportXpubCustomDerivationView, dict(seed=seed_12, sig_type="ss", script_type="")),
ScreenshotConfig(seed_views.SeedExportXpubQRFormatView, dict(seed=seed_12, sig_type="ss", script_type="nat")),
ScreenshotConfig(seed_views.SeedExportXpubWarningView, dict(seed=seed_12, sig_type="msig", script_type="nes", xpub_qr_format="urca", custom_derivation="")),
ScreenshotConfig(seed_views.SeedExportXpubDetailsView, dict(seed=seed_12, sig_type="ss", script_type="nat", xpub_qr_format="urca", custom_derivation="")),
ScreenshotConfig(SeedExportXpubQR_ScreenBrightnessView, dict(seed=seed_12, xpub_qr_format="urca", derivation_path="m/84'/0'/0'")),

ScreenshotConfig(seed_views.SeedWordsWarningView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedWordsView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedWordsView, dict(seed=seed_12, page_index=2), screenshot_name="SeedWordsView_2"),
ScreenshotConfig(seed_views.SeedBIP85SelectNumWordsView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedBIP85SelectChildIndexView, dict(seed=seed_12, num_words=24)),
ScreenshotConfig(seed_views.SeedBIP85InvalidChildIndexView, dict(seed=seed_12, num_words=12)),
ScreenshotConfig(seed_views.SeedWordsBackupTestPromptView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedWordsBackupTestView, dict(seed=seed_12, rand_seed=6102)),
ScreenshotConfig(seed_views.SeedWordsBackupTestMistakeView, dict(seed=seed_12, cur_index=7, wrong_word="satoshi")),
ScreenshotConfig(seed_views.SeedWordsBackupTestSuccessView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRFormatView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWarningView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed=seed_12, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=21), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed=seed_12, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Standard"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed=seed_24, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed=seed_24, seedqr_format=QRType.SEED__SEEDQR, num_modules=29), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Standard"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed=seed_12, seedqr_format=QRType.SEED__COMPACTSEEDQR, initial_zone_x=1, initial_zone_y=1), screenshot_name="SeedTranscribeSeedQRZoomedInView_12_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed=seed_12, seedqr_format=QRType.SEED__SEEDQR, initial_zone_x=2, initial_zone_y=2), screenshot_name="SeedTranscribeSeedQRZoomedInView_12_Standard"),

ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmQRPromptView, dict(seed=seed_12)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmWrongSeedView),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmInvalidQRView),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmSuccessView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmSuccessView, dict(seed=seed_12)),

# Screenshot can't render live preview screens
# ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmScanView, dict(seed_num=0)),
# ScreenshotConfig(seed_views.SeedTranscribeSeedQRConfirmScanView, dict(seed=seed_12)),

ScreenshotConfig(seed_views.SeedSelectSeedView, dict(flow=Controller.FLOW__VERIFY_SINGLESIG_ADDR), screenshot_name="SeedSelectSeedView_address_verification"),
ScreenshotConfig(seed_views.AddressVerificationSigTypeView),
ScreenshotConfig(seed_views.SeedAddressVerificationView, dict(seed_num=0), mock_context_manager=mock_address_verification_data_loaded),
ScreenshotConfig(seed_views.SeedAddressVerificationSuccessView, dict(seed_num=0), mock_context_manager=mock_address_verification_data_loaded),
ScreenshotConfig(seed_views.SeedAddressVerificationView, dict(seed=seed_12), mock_context_manager=mock_address_verification_data_loaded),
ScreenshotConfig(seed_views.SeedAddressVerificationSuccessView, mock_context_manager=mock_address_verification_data_loaded),

ScreenshotConfig(seed_views.LoadMultisigWalletDescriptorView),
ScreenshotConfig(seed_views.MultisigWalletDescriptorView, mock_context_manager=mock_multisig_wallet_descriptor_loaded),
ScreenshotConfig(seed_views.SeedDiscardView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedDiscardView, dict(seed=seed_12)),

ScreenshotConfig(seed_views.SeedSelectSeedView, dict(flow=Controller.FLOW__SIGN_MESSAGE), screenshot_name="SeedSelectSeedView_sign_message"),
ScreenshotConfig(seed_views.SeedSignMessageConfirmMessageView),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def test_initial_destination(self):
self.controller.storage.finalize_pending_seed()

self.run_sequence(
initial_destination_view_args=dict(seed_num=0),
initial_destination_view_args=dict(seed=seed),
sequence=[
FlowStep(SeedOptionsView, button_data_selection=SeedOptionsView.BACKUP),
FlowStep(SeedBackupView),
Expand Down
Loading