From b2cb263d680cc2c831422610704799d8e1a10164 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Mon, 26 Dec 2022 13:52:21 +0100 Subject: [PATCH] feature(@desktop/keycard): import or restore a Keycard via a seed phrase Fixes: #7029 --- .../main/profile_section/keycard/module.nim | 5 +- .../keycard_popup/controller.nim | 15 ++- .../internal/create_pin_state.nim | 2 + ...creating_account_new_seed_phrase_state.nim | 2 +- ...creating_account_old_seed_phrase_state.nim | 107 ++++++++++++++++++ .../internal/enter_keycard_name_state.nim | 8 +- .../internal/enter_pin_state.nim | 26 ++++- .../internal/enter_seed_phrase_state.nim | 32 ++++++ ..._confirmation_displayed_metadata_state.nim | 2 + .../factory_reset_confirmation_state.nim | 2 + .../internal/factory_reset_success_state.nim | 6 +- .../internal/insert_keycard_state.nim | 1 + ..._account_old_seed_phrase_failure_state.nim | 17 +++ ..._account_old_seed_phrase_success_state.nim | 17 +++ .../internal/keycard_empty_metadata_state.nim | 4 +- .../internal/keycard_inserted_state.nim | 1 + .../keycard_metadata_display_state.nim | 4 +- .../internal/keycard_not_empty_state.nim | 4 +- .../manage_keycard_accounts_state.nim | 12 +- .../max_pairing_slots_reached_state.nim | 4 +- .../max_pin_retries_reached_state.nim | 6 +- .../max_puk_retries_reached_state.nim | 4 +- .../internal/not_keycard_state.nim | 2 + .../keycard_popup/internal/pin_set_state.nim | 3 + .../internal/pin_verified_state.nim | 2 + .../internal/plugin_reader_state.nim | 1 + .../internal/recognized_keycard_state.nim | 4 +- .../internal/repeat_pin_state.nim | 14 ++- .../seed_phrase_already_in_use_state.nim | 14 +++ .../keycard_popup/internal/state.nim | 4 + .../keycard_popup/internal/state_factory.nim | 4 + .../state_factory_general_implementation.nim | 8 ++ .../state_factory_state_implementation.nim | 40 ++++++- .../internal/wrong_pin_state.nim | 22 +++- .../keycard_popup/io_interface.nim | 4 + .../shared_modules/keycard_popup/module.nim | 14 ++- .../shared/popups/keycard/KeycardPopup.qml | 2 + .../popups/keycard/KeycardPopupContent.qml | 4 + .../popups/keycard/KeycardPopupDetails.qml | 104 +++++++++++++++++ .../popups/keycard/states/EnterName.qml | 3 +- .../keycard/states/KeycardConfirmation.qml | 13 +++ .../popups/keycard/states/KeycardInit.qml | 70 +++++++++++- .../popups/keycard/states/ManageAccounts.qml | 4 +- ui/imports/utils/Constants.qml | 5 + 44 files changed, 588 insertions(+), 34 deletions(-) create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/creating_account_old_seed_phrase_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_failure_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_success_state.nim create mode 100644 src/app/modules/shared_modules/keycard_popup/internal/seed_phrase_already_in_use_state.nim diff --git a/src/app/modules/main/profile_section/keycard/module.nim b/src/app/modules/main/profile_section/keycard/module.nim index 6377090543..49ad649ded 100644 --- a/src/app/modules/main/profile_section/keycard/module.nim +++ b/src/app/modules/main/profile_section/keycard/module.nim @@ -122,7 +122,10 @@ method runCreateNewKeycardWithNewSeedPhrasePopup*(self: Module) = self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.SetupNewKeycardNewSeedPhrase) method runImportOrRestoreViaSeedPhrasePopup*(self: Module) = - info "TODO: Import or restore via a seed phrase..." + self.createSharedKeycardModule() + if self.keycardSharedModule.isNil: + return + self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.SetupNewKeycardOldSeedPhrase) method runImportFromKeycardToAppPopup*(self: Module) = info "TODO: Import from Keycard to Status Desktop..." diff --git a/src/app/modules/shared_modules/keycard_popup/controller.nim b/src/app/modules/shared_modules/keycard_popup/controller.nim index c5e9b806f3..d46be187ed 100644 --- a/src/app/modules/shared_modules/keycard_popup/controller.nim +++ b/src/app/modules/shared_modules/keycard_popup/controller.nim @@ -1,4 +1,4 @@ -import chronicles, strutils, os +import chronicles, strutils, os, sequtils, sugar import uuids import io_interface @@ -177,6 +177,9 @@ proc setContainsMetadata*(self: Controller, value: bool) = proc setKeyPairForProcessing*(self: Controller, item: KeyPairItem) = self.delegate.setKeyPairForProcessing(item) +proc prepareKeyPairForProcessing*(self: Controller, keyUid: string) = + self.delegate.prepareKeyPairForProcessing(keyUid) + proc getKeyPairForProcessing*(self: Controller): KeyPairItem = return self.delegate.getKeyPairForProcessing() @@ -516,6 +519,11 @@ proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAcco return return self.walletAccountService.fetchAccounts() +proc isKeyPairAlreadyAdded*(self: Controller, keyUid: string): bool = + let walletAccounts = self.getWalletAccounts() + let accountsForKeyUid = walletAccounts.filter(a => a.keyUid == keyUid) + return accountsForKeyUid.len > 0 + proc getCurrencyBalanceForAddress*(self: Controller, address: string): float64 = if not serviceApplicable(self.walletAccountService): return @@ -532,6 +540,11 @@ proc addMigratedKeyPair*(self: Controller, keyPair: KeyPairDto) = proc getAddingMigratedKeypairSuccess*(self: Controller): bool = return self.tmpAddingMigratedKeypairSuccess +proc getMigratedKeyPairByKeyUid*(self: Controller, keyUid: string): seq[KeyPairDto] = + if not serviceApplicable(self.walletAccountService): + return + return self.walletAccountService.getMigratedKeyPairByKeyUid(keyUid) + proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] = if not serviceApplicable(self.walletAccountService): return diff --git a/src/app/modules/shared_modules/keycard_popup/internal/create_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/create_pin_state.nim index c41e67e0c3..ce677a85ae 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/create_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/create_pin_state.nim @@ -18,6 +18,7 @@ method executePreBackStateCommand*(self: CreatePinState, controller: Controller) method executeCancelCommand*(self: CreatePinState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.ChangeKeycardPin: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) @@ -25,6 +26,7 @@ method executeCancelCommand*(self: CreatePinState, controller: Controller) = method getNextSecondaryState*(self: CreatePinState, controller: Controller): State = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.ChangeKeycardPin: if controller.getPin().len == PINLengthForStatusApp: diff --git a/src/app/modules/shared_modules/keycard_popup/internal/creating_account_new_seed_phrase_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/creating_account_new_seed_phrase_state.nim index 9252c85343..e4039f18d7 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/creating_account_new_seed_phrase_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/creating_account_new_seed_phrase_state.nim @@ -104,4 +104,4 @@ method resolveKeycardNextState*(self: CreatingAccountNewSeedPhraseState, keycard if keycardFlowType == ResponseTypeValueKeycardFlowResult and keycardEvent.error.len == 0: return createState(StateType.CreatingAccountNewSeedPhraseSuccess, self.flowType, nil) - return createState(StateType.CreatingAccountNewSeedPhraseSuccess, self.flowType, nil) \ No newline at end of file + return createState(StateType.CreatingAccountNewSeedPhraseFailure, self.flowType, nil) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/creating_account_old_seed_phrase_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/creating_account_old_seed_phrase_state.nim new file mode 100644 index 0000000000..e9a55e8a92 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/creating_account_old_seed_phrase_state.nim @@ -0,0 +1,107 @@ +type + CreatingAccountOldSeedPhraseState* = ref object of State + paths: seq[string] + addresses: seq[string] + +proc newCreatingAccountOldSeedPhraseState*(flowType: FlowType, backState: State): CreatingAccountOldSeedPhraseState = + result = CreatingAccountOldSeedPhraseState() + result.setup(flowType, StateType.CreatingAccountOldSeedPhrase, backState) + +proc delete*(self: CreatingAccountOldSeedPhraseState) = + self.State.delete + +proc resolvePaths(self: CreatingAccountOldSeedPhraseState, controller: Controller) = + let kpForPRocessing = controller.getKeyPairForProcessing() + var i = 0 + for account in kpForPRocessing.getAccountsModel().getItems(): + account.setPath(PATH_WALLET_ROOT & "/" & $i) + self.paths.add(account.getPath()) + i.inc + +proc findIndexForPath(self: CreatingAccountOldSeedPhraseState, path: string): int = + var ind = -1 + for p in self.paths: + ind.inc + if p == path: + return ind + return ind + +proc resolveAddresses(self: CreatingAccountOldSeedPhraseState, controller: Controller, keycardEvent: KeycardEvent): bool = + if keycardEvent.generatedWalletAccounts.len != self.paths.len: + return false + let kpForPRocessing = controller.getKeyPairForProcessing() + for account in kpForPRocessing.getAccountsModel().getItems(): + let index = self.findIndexForPath(account.getPath()) + if index == -1: + ## should never be here + return false + kpForPRocessing.setDerivedFrom(keycardEvent.masterKeyAddress) + account.setAddress(keycardEvent.generatedWalletAccounts[index].address) + account.setPubKey(keycardEvent.generatedWalletAccounts[index].publicKey) + self.addresses.add(keycardEvent.generatedWalletAccounts[index].address) + return true + +proc addAccountsToWallet(self: CreatingAccountOldSeedPhraseState, controller: Controller): bool = + let kpForPRocessing = controller.getKeyPairForProcessing() + for account in kpForPRocessing.getAccountsModel().getItems(): + if not controller.addWalletAccount(name = account.getName(), + address = account.getAddress(), + path = account.getPath(), + addressAccountIsDerivedFrom = kpForPRocessing.getDerivedFrom(), + publicKey = account.getPubKey(), + keyUid = kpForPRocessing.getKeyUid(), + accountType = if account.getPath() == PATH_DEFAULT_WALLET: SEED else: GENERATED, + color = account.getColor(), + emoji = account.getEmoji()): + return false + return true + +proc doMigration(self: CreatingAccountOldSeedPhraseState, controller: Controller) = + let kpForPRocessing = controller.getKeyPairForProcessing() + var kpDto = KeyPairDto(keycardUid: controller.getKeycardUid(), + keycardName: kpForPRocessing.getName(), + keycardLocked: false, + accountsAddresses: self.addresses, + keyUid: kpForPRocessing.getKeyUid()) + controller.addMigratedKeyPair(kpDto) + +proc runStoreMetadataFlow(self: CreatingAccountOldSeedPhraseState, controller: Controller) = + let kpForPRocessing = controller.getKeyPairForProcessing() + controller.runStoreMetadataFlow(kpForPRocessing.getName(), controller.getPin(), self.paths) + +method executePrePrimaryStateCommand*(self: CreatingAccountOldSeedPhraseState, controller: Controller) = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + self.resolvePaths(controller) + controller.runDeriveAccountFlow(bip44Paths = self.paths, controller.getPin()) + +method executePreSecondaryStateCommand*(self: CreatingAccountOldSeedPhraseState, controller: Controller) = + ## Secondary action is called after each async action during migration process, in this case after `addMigratedKeyPair`. + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if controller.getAddingMigratedKeypairSuccess(): + self.runStoreMetadataFlow(controller) + +method getNextSecondaryState*(self: CreatingAccountOldSeedPhraseState, controller: Controller): State = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if not controller.getAddingMigratedKeypairSuccess(): + return createState(StateType.CreatingAccountOldSeedPhraseFailure, self.flowType, nil) + +method resolveKeycardNextState*(self: CreatingAccountOldSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent, + controller: Controller): State = + let state = ensureReaderAndCardPresenceAndResolveNextState(self, keycardFlowType, keycardEvent, controller) + if not state.isNil: + return state + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if controller.getCurrentKeycardServiceFlow() == KCSFlowType.ExportPublic: + if keycardFlowType == ResponseTypeValueKeycardFlowResult and + keycardEvent.error.len == 0: + if not self.resolveAddresses(controller, keycardEvent): + return createState(StateType.CreatingAccountOldSeedPhraseFailure, self.flowType, nil) + if not self.addAccountsToWallet(controller): + return createState(StateType.CreatingAccountOldSeedPhraseFailure, self.flowType, nil) + self.doMigration(controller) + return nil # returning nil, cause we need to remain in this state + if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata: + if keycardFlowType == ResponseTypeValueKeycardFlowResult and + keycardEvent.error.len == 0: + return createState(StateType.CreatingAccountOldSeedPhraseSuccess, self.flowType, nil) + return createState(StateType.CreatingAccountOldSeedPhraseFailure, self.flowType, nil) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/enter_keycard_name_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/enter_keycard_name_state.nim index c9cb5f6257..1eb8839306 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/enter_keycard_name_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/enter_keycard_name_state.nim @@ -13,10 +13,12 @@ proc delete*(self: EnterKeycardNameState) = method getNextPrimaryState*(self: EnterKeycardNameState, controller: Controller): State = if self.flowType == FlowType.RenameKeycard: return createState(StateType.RenamingKeycard, self.flowType, nil) - if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: - return createState(StateType.ManageKeycardAccounts, self.flowType, self) + if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + return createState(StateType.ManageKeycardAccounts, self.flowType, self) method executeCancelCommand*(self: EnterKeycardNameState, controller: Controller) = if self.flowType == FlowType.RenameKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim index da8bf8c50b..25801eb944 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/enter_pin_state.nim @@ -12,7 +12,8 @@ method getNextPrimaryState*(self: EnterPinState, controller: Controller): State if self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.FactoryResetConfirmation, self.flowType, self) if self.flowType == FlowType.CreateCopyOfAKeycard: if isPredefinedKeycardDataFlagSet(controller.getKeycardData(), PredefinedKeycardData.CopyFromAKeycardPartDone): @@ -24,6 +25,7 @@ method getNextPrimaryState*(self: EnterPinState, controller: Controller): State method executePreSecondaryStateCommand*(self: EnterPinState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.FactoryReset or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or @@ -41,6 +43,7 @@ method executeCancelCommand*(self: EnterPinState, controller: Controller) = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or @@ -118,6 +121,27 @@ method resolveKeycardNextState*(self: EnterPinState, keycardFlowType: string, ke if keycardFlowType == ResponseTypeValueKeycardFlowResult: controller.setMetadataFromKeycard(keycardEvent.cardMetadata) return createState(StateType.PinVerified, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if keycardFlowType == ResponseTypeValueEnterPIN and + keycardEvent.error.len > 0 and + keycardEvent.error == ErrorPIN: + controller.setRemainingAttempts(keycardEvent.pinRetries) + if keycardEvent.pinRetries > 0: + return createState(StateType.WrongPin, self.flowType, nil) + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true)) + return createState(StateType.MaxPinRetriesReached, self.flowType, nil) + if keycardFlowType == ResponseTypeValueEnterPIN and + keycardEvent.error.len == 0: + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true)) + return createState(StateType.MaxPinRetriesReached, self.flowType, nil) + if keycardFlowType == ResponseTypeValueEnterPUK and + keycardEvent.error.len == 0: + if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0: + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true)) + return createState(StateType.MaxPinRetriesReached, self.flowType, nil) + if keycardFlowType == ResponseTypeValueKeycardFlowResult: + controller.setMetadataFromKeycard(keycardEvent.cardMetadata) + return createState(StateType.PinVerified, self.flowType, nil) if self.flowType == FlowType.Authentication: if keycardFlowType == ResponseTypeValueEnterPIN and keycardEvent.error.len > 0 and diff --git a/src/app/modules/shared_modules/keycard_popup/internal/enter_seed_phrase_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/enter_seed_phrase_state.nim index 6cdbbbf937..96b6d80d49 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/enter_seed_phrase_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/enter_seed_phrase_state.nim @@ -1,11 +1,15 @@ type EnterSeedPhraseState* = ref object of State verifiedSeedPhrase: bool + keyPairAlreadyMigrated: bool + keyPairAlreadyAdded: bool proc newEnterSeedPhraseState*(flowType: FlowType, backState: State): EnterSeedPhraseState = result = EnterSeedPhraseState() result.setup(flowType, StateType.EnterSeedPhrase, backState) result.verifiedSeedPhrase = false + result.keyPairAlreadyMigrated = false + result.keyPairAlreadyAdded = false proc delete*(self: EnterSeedPhraseState) = self.State.delete @@ -18,6 +22,20 @@ method executePrePrimaryStateCommand*(self: EnterSeedPhraseState, controller: Co controller.storeSeedPhraseToKeycard(controller.getSeedPhraseLength(), controller.getSeedPhrase()) else: controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WrongSeedPhrase, add = true)) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + self.verifiedSeedPhrase = controller.validSeedPhrase(controller.getSeedPhrase()) + if self.verifiedSeedPhrase: + ## should always be true, since it's not possible to do primary command otherwise (button is disabled on the UI) + let keyUid = controller.getKeyUidForSeedPhrase(controller.getSeedPhrase()) + self.keyPairAlreadyMigrated = controller.getMigratedKeyPairByKeyUid(keyUid).len > 0 + if self.keyPairAlreadyMigrated: + controller.prepareKeyPairForProcessing(keyUid) + return + self.keyPairAlreadyAdded = controller.isKeyPairAlreadyAdded(keyUid) + if self.keyPairAlreadyAdded: + controller.prepareKeyPairForProcessing(keyUid) + return + controller.storeSeedPhraseToKeycard(controller.getSeedPhraseLength(), controller.getSeedPhrase()) if self.flowType == FlowType.CreateCopyOfAKeycard: self.verifiedSeedPhrase = controller.validSeedPhrase(controller.getSeedPhrase()) and controller.getKeyUidForSeedPhrase(controller.getSeedPhrase()) == controller.getKeyPairForProcessing().getKeyUid() @@ -41,9 +59,18 @@ method getNextPrimaryState*(self: EnterSeedPhraseState, controller: Controller): if self.flowType == FlowType.CreateCopyOfAKeycard: if not self.verifiedSeedPhrase: return createState(StateType.WrongSeedPhrase, self.flowType, self.getBackState) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if not self.verifiedSeedPhrase: + ## we should never be here + return createState(StateType.WrongSeedPhrase, self.flowType, self.getBackState) + if self.keyPairAlreadyMigrated or self.keyPairAlreadyAdded: + ## Maybe we should differ among these 2 states (keyPairAlreadyMigrated or keyPairAlreadyAdded) + ## but we need to check that with designers. + return createState(StateType.SeedPhraseAlreadyInUse, self.flowType, self) method executeCancelCommand*(self: EnterSeedPhraseState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.CreateCopyOfAKeycard: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) @@ -57,6 +84,11 @@ method resolveKeycardNextState*(self: EnterSeedPhraseState, keycardFlowType: str if keycardFlowType == ResponseTypeValueKeycardFlowResult and keycardEvent.keyUid.len > 0: return createState(StateType.MigratingKeyPair, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if keycardFlowType == ResponseTypeValueEnterNewPIN and + keycardEvent.error.len > 0 and + keycardEvent.error == ErrorRequireInit: + return createState(StateType.CreatePin, self.flowType, nil) if self.flowType == FlowType.UnlockKeycard: if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: controller.setMetadataFromKeycard(keycardEvent.cardMetadata) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_displayed_metadata_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_displayed_metadata_state.nim index 4c3dc829c1..b96a2f5225 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_displayed_metadata_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_displayed_metadata_state.nim @@ -13,6 +13,7 @@ method executePrePrimaryStateCommand*(self: FactoryResetConfirmationDisplayMetad controller.runGetAppInfoFlow(factoryReset = true) elif self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.CreateCopyOfAKeycard: controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true)) controller.runGetAppInfoFlow(factoryReset = true) @@ -21,6 +22,7 @@ method executeCancelCommand*(self: FactoryResetConfirmationDisplayMetadataState, if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.CreateCopyOfAKeycard: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_state.nim index 0e45c3c2ab..2b3eb1ccfa 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_confirmation_state.nim @@ -13,6 +13,7 @@ method executePrePrimaryStateCommand*(self: FactoryResetConfirmationState, contr controller.runGetAppInfoFlow(factoryReset = true) elif self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.CreateCopyOfAKeycard: controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true)) controller.runGetAppInfoFlow(factoryReset = true) @@ -21,6 +22,7 @@ method executeCancelCommand*(self: FactoryResetConfirmationState, controller: Co if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.CreateCopyOfAKeycard: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_success_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_success_state.nim index 879f0fbdf7..33bfd6c27c 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_success_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/factory_reset_success_state.nim @@ -14,8 +14,9 @@ method executePrePrimaryStateCommand*(self: FactoryResetSuccessState, controller elif self.flowType == FlowType.SetupNewKeycard: controller.setSelectedKeypairAsKeyPairForProcessing() # we need to update keypair for next state (e.g. if user run into factory reset for example) controller.runLoadAccountFlow() - elif self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: - controller.runLoadAccountFlow() + elif self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.runLoadAccountFlow() elif self.flowType == FlowType.CreateCopyOfAKeycard: controller.setMetadataFromKeycard(controller.getMetadataForKeycardCopy()) # we need to update keypair for next state controller.runLoadAccountFlow(seedPhraseLength = 0, seedPhrase = "", pin = controller.getPinForKeycardCopy()) @@ -23,6 +24,7 @@ method executePrePrimaryStateCommand*(self: FactoryResetSuccessState, controller method executeCancelCommand*(self: FactoryResetSuccessState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.CreateCopyOfAKeycard: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim index 6be3c71338..0227e192de 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/insert_keycard_state.nim @@ -17,6 +17,7 @@ method executeCancelCommand*(self: InsertKeycardState, controller: Controller) = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_failure_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_failure_state.nim new file mode 100644 index 0000000000..33c092c2d2 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_failure_state.nim @@ -0,0 +1,17 @@ +type + CreatingAccountOldSeedPhraseFailureState* = ref object of State + +proc newCreatingAccountOldSeedPhraseFailureState*(flowType: FlowType, backState: State): CreatingAccountOldSeedPhraseFailureState = + result = CreatingAccountOldSeedPhraseFailureState() + result.setup(flowType, StateType.CreatingAccountOldSeedPhraseFailure, backState) + +proc delete*(self: CreatingAccountOldSeedPhraseFailureState) = + self.State.delete + +method executePrePrimaryStateCommand*(self: CreatingAccountOldSeedPhraseFailureState, controller: Controller) = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) + +method executeCancelCommand*(self: CreatingAccountOldSeedPhraseFailureState, controller: Controller) = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_success_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_success_state.nim new file mode 100644 index 0000000000..72c0c468f9 --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_create_account_old_seed_phrase_success_state.nim @@ -0,0 +1,17 @@ +type + CreatingAccountOldSeedPhraseSuccessState* = ref object of State + +proc newCreatingAccountOldSeedPhraseSuccessState*(flowType: FlowType, backState: State): CreatingAccountOldSeedPhraseSuccessState = + result = CreatingAccountOldSeedPhraseSuccessState() + result.setup(flowType, StateType.CreatingAccountOldSeedPhraseSuccess, backState) + +proc delete*(self: CreatingAccountOldSeedPhraseSuccessState) = + self.State.delete + +method executePrePrimaryStateCommand*(self: CreatingAccountOldSeedPhraseSuccessState, controller: Controller) = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) + +method executeCancelCommand*(self: CreatingAccountOldSeedPhraseSuccessState, controller: Controller) = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_metadata_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_metadata_state.nim index b85fe18a51..b5571c088c 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_metadata_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_empty_metadata_state.nim @@ -12,6 +12,7 @@ method executeCancelCommand*(self: KeycardEmptyMetadataState, controller: Contro if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or self.flowType == FlowType.CreateCopyOfAKeycard: @@ -28,7 +29,8 @@ method executePrePrimaryStateCommand*(self: KeycardEmptyMetadataState, controlle method getNextPrimaryState*(self: KeycardEmptyMetadataState, controller: Controller): State = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.FactoryResetConfirmation, self.flowType, self) if self.flowType == FlowType.CreateCopyOfAKeycard: if isPredefinedKeycardDataFlagSet(controller.getKeycardData(), PredefinedKeycardData.CopyFromAKeycardPartDone): diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim index d4d72aba16..6379eebbf2 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_inserted_state.nim @@ -24,6 +24,7 @@ method executeCancelCommand*(self: KeycardInsertedState, controller: Controller) if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_metadata_display_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_metadata_display_state.nim index f2dab3f214..089b47b69b 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/keycard_metadata_display_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_metadata_display_state.nim @@ -11,7 +11,8 @@ proc delete*(self: KeycardMetadataDisplayState) = method getNextPrimaryState*(self: KeycardMetadataDisplayState, controller: Controller): State = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.FactoryResetConfirmationDisplayMetadata, self.flowType, self) if self.flowType == FlowType.DisplayKeycardContent: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true) @@ -31,6 +32,7 @@ method executeCancelCommand*(self: KeycardMetadataDisplayState, controller: Cont if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or self.flowType == FlowType.CreateCopyOfAKeycard: diff --git a/src/app/modules/shared_modules/keycard_popup/internal/keycard_not_empty_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/keycard_not_empty_state.nim index 1f2cef9f2a..d6b280d02b 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/keycard_not_empty_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/keycard_not_empty_state.nim @@ -10,7 +10,8 @@ proc delete*(self: KeycardNotEmptyState) = method executePrePrimaryStateCommand*(self: KeycardNotEmptyState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true)) controller.runGetMetadataFlow(resolveAddress = true) return @@ -22,6 +23,7 @@ method executePrePrimaryStateCommand*(self: KeycardNotEmptyState, controller: Co method executeCancelCommand*(self: KeycardNotEmptyState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.CreateCopyOfAKeycard: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/manage_keycard_accounts_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/manage_keycard_accounts_state.nim index fde53f1a3e..7852cc2e25 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/manage_keycard_accounts_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/manage_keycard_accounts_state.nim @@ -13,11 +13,15 @@ proc delete*(self: ManageKeycardAccountsState) = method getNextPrimaryState*(self: ManageKeycardAccountsState, controller: Controller): State = if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: return createState(StateType.CreatingAccountNewSeedPhrase, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + return createState(StateType.CreatingAccountOldSeedPhrase, self.flowType, nil) method executePreSecondaryStateCommand*(self: ManageKeycardAccountsState, controller: Controller) = - if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: - controller.getKeyPairForProcessing().addAccount(newKeyPairAccountItem()) + if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.getKeyPairForProcessing().addAccount(newKeyPairAccountItem()) method executeCancelCommand*(self: ManageKeycardAccountsState, controller: Controller) = - if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: - controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) + if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) diff --git a/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim index 3925ecebb9..b9ef3fddde 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/max_pairing_slots_reached_state.nim @@ -11,7 +11,8 @@ proc delete*(self: MaxPairingSlotsReachedState) = method getNextPrimaryState*(self: MaxPairingSlotsReachedState, controller: Controller): State = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.FactoryResetConfirmation, self.flowType, self) if self.flowType == FlowType.Authentication or self.flowType == FlowType.DisplayKeycardContent or @@ -28,6 +29,7 @@ method executeCancelCommand*(self: MaxPairingSlotsReachedState, controller: Cont if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim index 9e963cbf7d..c8e5a985f8 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/max_pin_retries_reached_state.nim @@ -20,7 +20,8 @@ method getNextPrimaryState*(self: MaxPinRetriesReachedState, controller: Control controller.runSharedModuleFlow(FlowType.UnlockKeycard) if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: let currValue = extractPredefinedKeycardDataToNumber(controller.getKeycardData()) if (currValue and PredefinedKeycardData.DisableSeedPhraseForUnlock.int) > 0: controller.runSharedModuleFlow(FlowType.UnlockKeycard) @@ -40,6 +41,7 @@ method executeCancelCommand*(self: MaxPinRetriesReachedState, controller: Contro if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = false)) controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim index f0f93cc4cf..d1e587aba1 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/max_puk_retries_reached_state.nim @@ -11,7 +11,8 @@ proc delete*(self: MaxPukRetriesReachedState) = method getNextPrimaryState*(self: MaxPukRetriesReachedState, controller: Controller): State = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.FactoryResetConfirmation, self.flowType, self) if self.flowType == FlowType.Authentication or self.flowType == FlowType.DisplayKeycardContent or @@ -28,6 +29,7 @@ method executeCancelCommand*(self: MaxPukRetriesReachedState, controller: Contro if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim index 61bb723b46..d9dc0f50d2 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/not_keycard_state.nim @@ -11,6 +11,8 @@ proc delete*(self: NotKeycardState) = method executeCancelCommand*(self: NotKeycardState, controller: Controller) = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim index a23591143c..f756f28fad 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/pin_set_state.nim @@ -16,6 +16,8 @@ method getNextPrimaryState*(self: PinSetState, controller: Controller): State = return createState(StateType.SeedPhraseDisplay, self.flowType, nil) if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: return createState(StateType.SeedPhraseDisplay, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + return createState(StateType.EnterKeycardName, self.flowType, nil) if self.flowType == FlowType.UnlockKeycard: if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: if controller.getValidPuk(): @@ -27,5 +29,6 @@ method getNextPrimaryState*(self: PinSetState, controller: Controller): State = method executeCancelCommand*(self: PinSetState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.UnlockKeycard: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim index 75bd2bcf29..0bd651623f 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/pin_verified_state.nim @@ -12,6 +12,7 @@ method getNextPrimaryState*(self: PinVerifiedState, controller: Controller): Sta if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or self.flowType == FlowType.CreateCopyOfAKeycard: @@ -27,6 +28,7 @@ method executeCancelCommand*(self: PinVerifiedState, controller: Controller) = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or self.flowType == FlowType.ChangeKeycardPin or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim index 55d9e8324c..7b46e86571 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/plugin_reader_state.nim @@ -17,6 +17,7 @@ method executeCancelCommand*(self: PluginReaderState, controller: Controller) = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim index bfa4eef2c2..7157042c99 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/recognized_keycard_state.nim @@ -22,7 +22,9 @@ method getNextSecondaryState*(self: RecognizedKeycardState, controller: Controll if self.flowType == FlowType.SetupNewKeycard: return createState(StateType.CreatePin, self.flowType, self.getBackState) if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: - return createState(StateType.CreatePin, self.flowType, nil) + return createState(StateType.CreatePin, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + return createState(StateType.EnterSeedPhrase, self.flowType, nil) if self.flowType == FlowType.UnlockKeycard: return createState(StateType.UnlockKeycardOptions, self.flowType, nil) if self.flowType == FlowType.DisplayKeycardContent or diff --git a/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim index b10a708954..4609050689 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/repeat_pin_state.nim @@ -16,7 +16,8 @@ method executePreSecondaryStateCommand*(self: RepeatPinState, controller: Contro if not controller.getPinMatch(): return if self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: controller.storePinToKeycard(controller.getPin(), controller.generateRandomPUK()) if self.flowType == FlowType.UnlockKeycard: controller.storePinToKeycard(controller.getPin(), "") @@ -30,6 +31,7 @@ method getNextSecondaryState*(self: RepeatPinState, controller: Controller): Sta method executeCancelCommand*(self: RepeatPinState, controller: Controller) = if self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.UnlockKeycard or self.flowType == FlowType.ChangeKeycardPin: controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) @@ -51,6 +53,16 @@ method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, k keycardEvent.error == ErrorLoadingKeys: controller.buildSeedPhrasesFromIndexes(keycardEvent.seedPhraseIndexes) return createState(StateType.PinSet, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if keycardFlowType == ResponseTypeValueKeycardFlowResult and + keycardEvent.keyUid.len > 0: + controller.setKeycardUid(keycardEvent.instanceUID) + var item = newKeyPairItem(keyUid = keycardEvent.keyUid) + item.setIcon("keycard") + item.setPairType(KeyPairType.SeedImport.int) + item.addAccount(newKeyPairAccountItem()) + controller.setKeyPairForProcessing(item) + return createState(StateType.PinSet, self.flowType, nil) if self.flowType == FlowType.UnlockKeycard: if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: if keycardFlowType == ResponseTypeValueEnterPUK and diff --git a/src/app/modules/shared_modules/keycard_popup/internal/seed_phrase_already_in_use_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/seed_phrase_already_in_use_state.nim new file mode 100644 index 0000000000..605dbfc05b --- /dev/null +++ b/src/app/modules/shared_modules/keycard_popup/internal/seed_phrase_already_in_use_state.nim @@ -0,0 +1,14 @@ +type + SeedPhraseAlreadyInUseState* = ref object of State + verifiedSeedPhrase: bool + +proc newSeedPhraseAlreadyInUseState*(flowType: FlowType, backState: State): SeedPhraseAlreadyInUseState = + result = SeedPhraseAlreadyInUseState() + result.setup(flowType, StateType.SeedPhraseAlreadyInUse, backState) + +proc delete*(self: SeedPhraseAlreadyInUseState) = + self.State.delete + +method executeCancelCommand*(self: SeedPhraseAlreadyInUseState, controller: Controller) = + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) \ No newline at end of file diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state.nim b/src/app/modules/shared_modules/keycard_popup/internal/state.nim index a231ba4e5f..5f8eaeb5d6 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state.nim @@ -39,6 +39,7 @@ type StateType* {.pure.} = enum SelectExistingKeyPair = "SelectExistingKeyPair" EnterSeedPhrase = "EnterSeedPhrase" WrongSeedPhrase = "WrongSeedPhrase" + SeedPhraseAlreadyInUse = "SeedPhraseAlreadyInUse" SeedPhraseDisplay = "SeedPhraseDisplay" SeedPhraseEnterWords = "SeedPhraseEnterWords" KeyPairMigrateSuccess = "KeyPairMigrateSuccess" @@ -78,6 +79,9 @@ type StateType* {.pure.} = enum CreatingAccountNewSeedPhrase = "CreatingAccountNewSeedPhrase" CreatingAccountNewSeedPhraseSuccess = "CreatingAccountNewSeedPhraseSuccess" CreatingAccountNewSeedPhraseFailure = "CreatingAccountNewSeedPhraseFailure" + CreatingAccountOldSeedPhrase = "CreatingAccountOldSeedPhrase" + CreatingAccountOldSeedPhraseSuccess = "CreatingAccountOldSeedPhraseSuccess" + CreatingAccountOldSeedPhraseFailure = "CreatingAccountOldSeedPhraseFailure" ## This is the base class for all state we may have in onboarding/login flow. diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim b/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim index ad7f02b96d..017f288f25 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state_factory.nim @@ -48,6 +48,7 @@ include create_pairing_code_state include create_pin_state include create_puk_state include creating_account_new_seed_phrase_state +include creating_account_old_seed_phrase_state include enter_biometrics_password_state include enter_keycard_name_state include enter_password_state @@ -70,6 +71,8 @@ include keycard_copy_failure_state include keycard_copy_success_state include keycard_create_account_new_seed_phrase_failure_state include keycard_create_account_new_seed_phrase_success_state +include keycard_create_account_old_seed_phrase_failure_state +include keycard_create_account_old_seed_phrase_success_state include keycard_empty_metadata_state include keycard_empty_state include keycard_inserted_state @@ -94,6 +97,7 @@ include renaming_keycard_state include repeat_pin_state include repeat_puk_state include same_keycard_state +include seed_phrase_already_in_use_state include seed_phrase_display_state include seed_phrase_enter_words_state include select_existing_key_pair_state diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim b/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim index 9428060a6a..2b8abac4dc 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state_factory_general_implementation.nim @@ -57,6 +57,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St return newCreatePukState(flowType, backState) if stateToBeCreated == StateType.CreatingAccountNewSeedPhrase: return newCreatingAccountNewSeedPhraseState(flowType, backState) + if stateToBeCreated == StateType.CreatingAccountOldSeedPhrase: + return newCreatingAccountOldSeedPhraseState(flowType, backState) if stateToBeCreated == StateType.EnterBiometricsPassword: return newEnterBiometricsPasswordState(flowType, backState) if stateToBeCreated == StateType.EnterKeycardName: @@ -101,6 +103,10 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St return newCreatingAccountNewSeedPhraseFailureState(flowType, backState) if stateToBeCreated == StateType.CreatingAccountNewSeedPhraseSuccess: return newCreatingAccountNewSeedPhraseSuccessState(flowType, backState) + if stateToBeCreated == StateType.CreatingAccountOldSeedPhraseFailure: + return newCreatingAccountOldSeedPhraseFailureState(flowType, backState) + if stateToBeCreated == StateType.CreatingAccountOldSeedPhraseSuccess: + return newCreatingAccountOldSeedPhraseSuccessState(flowType, backState) if stateToBeCreated == StateType.KeycardInserted: return newKeycardInsertedState(flowType, backState) if stateToBeCreated == StateType.KeycardEmptyMetadata: @@ -155,6 +161,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St return newSameKeycardState(flowType, backState) if stateToBeCreated == StateType.SeedPhraseDisplay: return newSeedPhraseDisplayState(flowType, backState) + if stateToBeCreated == StateType.SeedPhraseAlreadyInUse: + return newSeedPhraseAlreadyInUseState(flowType, backState) if stateToBeCreated == StateType.SeedPhraseEnterWords: return newSeedPhraseEnterWordsState(flowType, backState) if stateToBeCreated == StateType.SelectExistingKeyPair: diff --git a/src/app/modules/shared_modules/keycard_popup/internal/state_factory_state_implementation.nim b/src/app/modules/shared_modules/keycard_popup/internal/state_factory_state_implementation.nim index 5633389ae9..75c8608d7d 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/state_factory_state_implementation.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/state_factory_state_implementation.nim @@ -9,7 +9,8 @@ proc ensureReaderAndCardPresence*(state: State, keycardFlowType: string, keycard state.flowType == FlowType.ChangeKeycardPuk or state.flowType == FlowType.ChangePairingCode or state.flowType == FlowType.CreateCopyOfAKeycard or - state.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + state.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + state.flowType == FlowType.SetupNewKeycardOldSeedPhrase: if keycardFlowType == ResponseTypeValueKeycardFlowResult and keycardEvent.error.len > 0 and keycardEvent.error == ErrorConnection: @@ -170,6 +171,43 @@ proc ensureReaderAndCardPresenceAndResolveNextState*(state: State, keycardFlowTy keycardEvent.error == ErrorRequireInit: return createState(StateType.RecognizedKeycard, state.flowType, nil) + ## Handling setup new keycard new seed phrase flow + if state.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if keycardFlowType == ResponseTypeValueSwapCard and + keycardEvent.error.len > 0: + if keycardEvent.error == ErrorNotAKeycard: + return createState(StateType.NotKeycard, state.flowType, nil) + if keycardEvent.error == ErrorHasKeys: + return createState(StateType.KeycardNotEmpty, state.flowType, nil) + if keycardEvent.error == ErrorFreePairingSlots: + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseGeneralMessageForLockedState, add = true)) + return createState(StateType.MaxPairingSlotsReached, state.flowType, nil) + if keycardEvent.error == ErrorPUKRetries: + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseGeneralMessageForLockedState, add = true)) + return createState(StateType.MaxPukRetriesReached, state.flowType, nil) + if keycardFlowType == ResponseTypeValueEnterPIN: + if controller.getCurrentKeycardServiceFlow() == KCSFlowType.GetMetadata: + return createState(StateType.EnterPin, state.flowType, nil) + return createState(StateType.KeycardNotEmpty, state.flowType, nil) + if keycardFlowType == ResponseTypeValueEnterPUK and + keycardEvent.error.len == 0: + if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0: + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.UseGeneralMessageForLockedState, add = true)) + return createState(StateType.MaxPinRetriesReached, state.flowType, nil) + if keycardFlowType == ResponseTypeValueKeycardFlowResult and + keycardEvent.error.len > 0: + controller.setKeycardData("") + if keycardEvent.error == ErrorOk: + return createState(StateType.FactoryResetSuccess, state.flowType, nil) + if keycardEvent.error == ErrorNoData: + return createState(StateType.KeycardEmptyMetadata, state.flowType, nil) + if keycardEvent.error == ErrorNoKeys: + return createState(StateType.KeycardEmptyMetadata, state.flowType, nil) + if keycardFlowType == ResponseTypeValueEnterNewPIN and + keycardEvent.error.len > 0 and + keycardEvent.error == ErrorRequireInit: + return createState(StateType.RecognizedKeycard, state.flowType, nil) + ## Handling authentiaction flow if state.flowType == FlowType.Authentication: if keycardFlowType == ResponseTypeValueSwapCard and diff --git a/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim b/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim index c5315bbfff..cb553b3b52 100644 --- a/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim +++ b/src/app/modules/shared_modules/keycard_popup/internal/wrong_pin_state.nim @@ -11,7 +11,8 @@ proc delete*(self: WrongPinState) = method getNextPrimaryState*(self: WrongPinState, controller: Controller): State = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or - self.flowType == FlowType.SetupNewKeycardNewSeedPhrase: + self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: return createState(StateType.FactoryResetConfirmation, self.flowType, self) if self.flowType == FlowType.CreateCopyOfAKeycard: if isPredefinedKeycardDataFlagSet(controller.getKeycardData(), PredefinedKeycardData.CopyFromAKeycardPartDone): @@ -30,6 +31,7 @@ method executePreSecondaryStateCommand*(self: WrongPinState, controller: Control if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or self.flowType == FlowType.ChangeKeycardPin or @@ -46,6 +48,7 @@ method executeCancelCommand*(self: WrongPinState, controller: Controller) = if self.flowType == FlowType.FactoryReset or self.flowType == FlowType.SetupNewKeycard or self.flowType == FlowType.SetupNewKeycardNewSeedPhrase or + self.flowType == FlowType.SetupNewKeycardOldSeedPhrase or self.flowType == FlowType.Authentication or self.flowType == FlowType.DisplayKeycardContent or self.flowType == FlowType.RenameKeycard or @@ -111,6 +114,23 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke if keycardFlowType == ResponseTypeValueKeycardFlowResult: controller.setMetadataFromKeycard(keycardEvent.cardMetadata) return createState(StateType.PinVerified, self.flowType, nil) + if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase: + if keycardFlowType == ResponseTypeValueEnterPIN and + keycardEvent.error.len > 0 and + keycardEvent.error == ErrorPIN: + controller.setRemainingAttempts(keycardEvent.pinRetries) + if keycardEvent.pinRetries > 0: + return self + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true)) + return createState(StateType.MaxPinRetriesReached, self.flowType, nil) + if keycardFlowType == ResponseTypeValueEnterPUK and + keycardEvent.error.len == 0: + if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0: + controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true)) + return createState(StateType.MaxPinRetriesReached, self.flowType, nil) + if keycardFlowType == ResponseTypeValueKeycardFlowResult: + controller.setMetadataFromKeycard(keycardEvent.cardMetadata) + return createState(StateType.PinVerified, self.flowType, nil) if self.flowType == FlowType.Authentication: if keycardFlowType == ResponseTypeValueEnterPIN and keycardEvent.error.len > 0 and diff --git a/src/app/modules/shared_modules/keycard_popup/io_interface.nim b/src/app/modules/shared_modules/keycard_popup/io_interface.nim index 1970df2e6d..bf042a877b 100644 --- a/src/app/modules/shared_modules/keycard_popup/io_interface.nim +++ b/src/app/modules/shared_modules/keycard_popup/io_interface.nim @@ -50,6 +50,7 @@ type FlowType* {.pure.} = enum FactoryReset = "FactoryReset" SetupNewKeycard = "SetupNewKeycard" SetupNewKeycardNewSeedPhrase = "SetupNewKeycardNewSeedPhrase" + SetupNewKeycardOldSeedPhrase = "SetupNewKeycardOldSeedPhrase" Authentication = "Authentication" UnlockKeycard = "UnlockKeycard" DisplayKeycardContent = "DisplayKeycardContent" @@ -152,6 +153,9 @@ method updateKeyPairForProcessing*(self: AccessInterface, cardMetadata: CardMeta method setKeyPairForProcessing*(self: AccessInterface, item: KeyPairItem) {.base.} = raise newException(ValueError, "No implementation available") +method prepareKeyPairForProcessing*(self: AccessInterface, keyUid: string, keycardUid = "") {.base.} = + raise newException(ValueError, "No implementation available") + method migratingProfileKeyPair*(self: AccessInterface): bool {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/shared_modules/keycard_popup/module.nim b/src/app/modules/shared_modules/keycard_popup/module.nim index 8d1bdaf693..7ed4fa5fdc 100644 --- a/src/app/modules/shared_modules/keycard_popup/module.nim +++ b/src/app/modules/shared_modules/keycard_popup/module.nim @@ -57,9 +57,6 @@ proc newModule*[T](delegate: T, result.derivingAccountDetails.deriveAddressAfterAuthentication = false result.derivingAccountDetails.addressRequested = false -## Forward declaration -proc prepareKeyPairForProcessing[T](self: Module[T], keyUid: string, keycardUid = "") - method delete*[T](self: Module[T]) = self.view.delete self.viewVariant.delete @@ -132,8 +129,9 @@ method getMnemonic*[T](self: Module[T]): string = return if currStateObj.flowType() == FlowType.SetupNewKeycard: return self.controller.getProfileMnemonic() - if currStateObj.flowType() == FlowType.SetupNewKeycardNewSeedPhrase: - return self.controller.getSeedPhrase() + if currStateObj.flowType() == FlowType.SetupNewKeycardNewSeedPhrase or + currStateObj.flowType() == FlowType.SetupNewKeycardOldSeedPhrase: + return self.controller.getSeedPhrase() method setSeedPhrase*[T](self: Module[T], value: string) = self.controller.setSeedPhrase(value) @@ -363,7 +361,7 @@ method setKeyPairForProcessing*[T](self: Module[T], item: KeyPairItem) = return self.view.setKeyPairForProcessing(item) -proc prepareKeyPairForProcessing[T](self: Module[T], keyUid: string, keycardUid = "") = +method prepareKeyPairForProcessing*[T](self: Module[T], keyUid: string, keycardUid = "") = var item = newKeyPairItem() let items = self.buildKeyPairsList(excludeAlreadyMigratedPairs = false) for it in items: @@ -465,6 +463,10 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path self.tmpLocalState = newReadingKeycardState(flowToRun, nil) self.controller.runLoadAccountFlow() return + if flowToRun == FlowType.SetupNewKeycardOldSeedPhrase: + self.tmpLocalState = newReadingKeycardState(flowToRun, nil) + self.controller.runLoadAccountFlow() + return method setSelectedKeyPair*[T](self: Module[T], item: KeyPairItem) = var paths: seq[string] diff --git a/ui/imports/shared/popups/keycard/KeycardPopup.qml b/ui/imports/shared/popups/keycard/KeycardPopup.qml index 187fc8dd14..fe0e482c3f 100644 --- a/ui/imports/shared/popups/keycard/KeycardPopup.qml +++ b/ui/imports/shared/popups/keycard/KeycardPopup.qml @@ -21,6 +21,8 @@ StatusModal { return qsTr("Set up a new Keycard with an existing account") case Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase: return qsTr("Create a new Keycard account with a new seed phrase") + case Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase: + return qsTr("Import or restore a Keycard via a seed phrase") case Constants.keycardSharedFlow.factoryReset: return qsTr("Factory reset a Keycard") case Constants.keycardSharedFlow.authentication: diff --git a/ui/imports/shared/popups/keycard/KeycardPopupContent.qml b/ui/imports/shared/popups/keycard/KeycardPopupContent.qml index 8d7b05cd04..432731452c 100644 --- a/ui/imports/shared/popups/keycard/KeycardPopupContent.qml +++ b/ui/imports/shared/popups/keycard/KeycardPopupContent.qml @@ -34,6 +34,9 @@ Item { case Constants.keycardSharedState.creatingAccountNewSeedPhraseSuccess: case Constants.keycardSharedState.creatingAccountNewSeedPhraseFailure: case Constants.keycardSharedState.creatingAccountNewSeedPhrase: + case Constants.keycardSharedState.creatingAccountOldSeedPhraseSuccess: + case Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure: + case Constants.keycardSharedState.creatingAccountOldSeedPhrase: case Constants.keycardSharedState.keycardRenameSuccess: case Constants.keycardSharedState.keycardRenameFailure: case Constants.keycardSharedState.renamingKeycard: @@ -68,6 +71,7 @@ Item { case Constants.keycardSharedState.copyingKeycard: case Constants.keycardSharedState.copyingKeycardSuccess: case Constants.keycardSharedState.copyingKeycardFailure: + case Constants.keycardSharedState.seedPhraseAlreadyInUse: return initComponent case Constants.keycardSharedState.factoryResetConfirmation: diff --git a/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml b/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml index 691d89dd16..6922c796a9 100644 --- a/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml +++ b/ui/imports/shared/popups/keycard/KeycardPopupDetails.qml @@ -22,6 +22,7 @@ QtObject { case Constants.keycardSharedState.changingKeycardPairingCode: case Constants.keycardSharedState.migratingKeyPair: case Constants.keycardSharedState.creatingAccountNewSeedPhrase: + case Constants.keycardSharedState.creatingAccountOldSeedPhrase: case Constants.keycardSharedState.copyingKeycard: return true @@ -100,6 +101,34 @@ QtObject { } break + case Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase: + switch (root.sharedKeycardModule.currentState.stateType) { + case Constants.keycardSharedState.pluginReader: + case Constants.keycardSharedState.readingKeycard: + case Constants.keycardSharedState.insertKeycard: + case Constants.keycardSharedState.keycardInserted: + case Constants.keycardSharedState.recognizedKeycard: + case Constants.keycardSharedState.keycardNotEmpty: + case Constants.keycardSharedState.keycardEmptyMetadata: + case Constants.keycardSharedState.notKeycard: + case Constants.keycardSharedState.enterPin: + case Constants.keycardSharedState.wrongPin: + case Constants.keycardSharedState.createPin: + case Constants.keycardSharedState.repeatPin: + case Constants.keycardSharedState.maxPinRetriesReached: + case Constants.keycardSharedState.maxPukRetriesReached: + case Constants.keycardSharedState.maxPairingSlotsReached: + case Constants.keycardSharedState.factoryResetConfirmation: + case Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata: + case Constants.keycardSharedState.factoryResetSuccess: + case Constants.keycardSharedState.pinVerified: + case Constants.keycardSharedState.keycardMetadataDisplay: + case Constants.keycardSharedState.enterSeedPhrase: + case Constants.keycardSharedState.seedPhraseAlreadyInUse: + return true + } + break + case Constants.keycardSharedFlow.factoryReset: switch (root.sharedKeycardModule.currentState.stateType) { case Constants.keycardSharedState.pluginReader: @@ -305,6 +334,7 @@ QtObject { case Constants.keycardSharedState.readingKeycard: case Constants.keycardSharedState.migratingKeyPair: case Constants.keycardSharedState.creatingAccountNewSeedPhrase: + case Constants.keycardSharedState.creatingAccountOldSeedPhrase: case Constants.keycardSharedState.renamingKeycard: case Constants.keycardSharedState.changingKeycardPin: case Constants.keycardSharedState.changingKeycardPuk: @@ -385,6 +415,13 @@ QtObject { return qsTr("Add another account") } break + + case Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase: + switch (root.sharedKeycardModule.currentState.stateType) { + case Constants.keycardSharedState.manageKeycardAccounts: + return qsTr("Add another account") + } + break } return "" @@ -397,6 +434,7 @@ QtObject { case Constants.keycardSharedState.readingKeycard: case Constants.keycardSharedState.migratingKeyPair: case Constants.keycardSharedState.creatingAccountNewSeedPhrase: + case Constants.keycardSharedState.creatingAccountOldSeedPhrase: case Constants.keycardSharedState.renamingKeycard: case Constants.keycardSharedState.changingKeycardPin: case Constants.keycardSharedState.changingKeycardPuk: @@ -434,6 +472,14 @@ QtObject { case Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase: switch (root.sharedKeycardModule.currentState.stateType) { + case Constants.keycardSharedState.manageKeycardAccounts: + return root.primaryButtonEnabled + } + break + + case Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase: + switch (root.sharedKeycardModule.currentState.stateType) { + case Constants.keycardSharedState.manageKeycardAccounts: return root.primaryButtonEnabled } @@ -557,6 +603,47 @@ QtObject { } break + case Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase: + switch (root.sharedKeycardModule.currentState.stateType) { + case Constants.keycardSharedState.keycardNotEmpty: + return qsTr("Check what is stored on this Keycard") + + case Constants.keycardSharedState.enterPin: + case Constants.keycardSharedState.wrongPin: + return qsTr("I don’t know the PIN") + + case Constants.keycardSharedState.factoryResetConfirmation: + case Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata: + return qsTr("Factory reset this Keycard") + + case Constants.keycardSharedState.keycardEmptyMetadata: + case Constants.keycardSharedState.keycardMetadataDisplay: + case Constants.keycardSharedState.factoryResetSuccess: + case Constants.keycardSharedState.createPin: + case Constants.keycardSharedState.repeatPin: + case Constants.keycardSharedState.pinVerified: + case Constants.keycardSharedState.pinSet: + case Constants.keycardSharedState.enterKeycardName: + case Constants.keycardSharedState.enterSeedPhrase: + return qsTr("Next") + + case Constants.keycardSharedState.maxPinRetriesReached: + case Constants.keycardSharedState.maxPukRetriesReached: + case Constants.keycardSharedState.maxPairingSlotsReached: + if (root.sharedKeycardModule.keycardData & Constants.predefinedKeycardData.disableSeedPhraseForUnlock) + return qsTr("Unlock Keycard") + return qsTr("Next") + + case Constants.keycardSharedState.creatingAccountOldSeedPhrase: + case Constants.keycardSharedState.creatingAccountOldSeedPhraseSuccess: + case Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure: + return qsTr("Done") + + case Constants.keycardSharedState.manageKeycardAccounts: + return qsTr("Finalise Keycard") + } + break + case Constants.keycardSharedFlow.factoryReset: switch (root.sharedKeycardModule.currentState.stateType) { @@ -848,6 +935,7 @@ QtObject { case Constants.keycardSharedState.readingKeycard: case Constants.keycardSharedState.migratingKeyPair: case Constants.keycardSharedState.creatingAccountNewSeedPhrase: + case Constants.keycardSharedState.creatingAccountOldSeedPhrase: case Constants.keycardSharedState.renamingKeycard: case Constants.keycardSharedState.changingKeycardPin: case Constants.keycardSharedState.changingKeycardPuk: @@ -897,6 +985,22 @@ QtObject { } break + case Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase: + switch (root.sharedKeycardModule.currentState.stateType) { + + case Constants.keycardSharedState.factoryResetConfirmation: + case Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata: + case Constants.keycardSharedState.enterKeycardName: + case Constants.keycardSharedState.manageKeycardAccounts: + case Constants.keycardSharedState.enterSeedPhrase: + return root.primaryButtonEnabled + + case Constants.keycardSharedState.createPin: + case Constants.keycardSharedState.repeatPin: + return false + } + break + case Constants.keycardSharedFlow.factoryReset: switch (root.sharedKeycardModule.currentState.stateType) { diff --git a/ui/imports/shared/popups/keycard/states/EnterName.qml b/ui/imports/shared/popups/keycard/states/EnterName.qml index 7a42e2b85f..98526f2a3e 100644 --- a/ui/imports/shared/popups/keycard/states/EnterName.qml +++ b/ui/imports/shared/popups/keycard/states/EnterName.qml @@ -32,7 +32,8 @@ Item { } Component.onCompleted: { - if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase) { + if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase) { if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.enterKeycardName) { if (root.sharedKeycardModule.keyPairForProcessing.name.trim() !== "") { d.updateValidity() diff --git a/ui/imports/shared/popups/keycard/states/KeycardConfirmation.qml b/ui/imports/shared/popups/keycard/states/KeycardConfirmation.qml index 840da0577f..6760ca4c9c 100644 --- a/ui/imports/shared/popups/keycard/states/KeycardConfirmation.qml +++ b/ui/imports/shared/popups/keycard/states/KeycardConfirmation.qml @@ -112,6 +112,11 @@ Item { return true } } + if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase) { + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata) { + return true + } + } if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata) { return true @@ -142,6 +147,14 @@ Item { return unknownKeyPairCompontnt } } + if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase) { + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata) { + if (root.sharedKeycardModule.keyPairStoredOnKeycardIsKnown) { + return keyPairForProcessingComponent + } + return unknownKeyPairCompontnt + } + } if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetConfirmationDisplayMetadata) { if (root.sharedKeycardModule.keyPairStoredOnKeycardIsKnown) { diff --git a/ui/imports/shared/popups/keycard/states/KeycardInit.qml b/ui/imports/shared/popups/keycard/states/KeycardInit.qml index 62f81c5d2e..03b9255f44 100644 --- a/ui/imports/shared/popups/keycard/states/KeycardInit.qml +++ b/ui/imports/shared/popups/keycard/states/KeycardInit.qml @@ -18,6 +18,7 @@ Item { Component.onCompleted: { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhrase || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.copyingKeycard) { root.sharedKeycardModule.currentState.doPrimaryAction() @@ -31,6 +32,7 @@ Item { readonly property bool copyFromAKeycardPartDone: root.sharedKeycardModule.keycardData & Constants.predefinedKeycardData.copyFromAKeycardPartDone readonly property bool continuousProcessingAnimation: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhrase || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.copyingKeycard } @@ -127,6 +129,7 @@ Item { visible: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhrase || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk || @@ -144,6 +147,7 @@ Item { Layout.alignment: Qt.AlignCenter Layout.preferredWidth: parent.width Layout.preferredHeight: Constants.keycard.general.messageHeight + Layout.fillHeight: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.seedPhraseAlreadyInUse horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap } @@ -173,6 +177,15 @@ Item { return true } } + if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase) { + if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseSuccess || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.seedPhraseAlreadyInUse) { + return true + } + } if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) { if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay) { return true @@ -301,6 +314,21 @@ Item { return keyPairForProcessingComponent } } + if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase) { + if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay) { + if (root.sharedKeycardModule.keyPairStoredOnKeycardIsKnown) { + return keyPairForProcessingComponent + } + return unknownKeyPairCompontnt + } + + if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseSuccess || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.seedPhraseAlreadyInUse) { + return keyPairForProcessingComponent + } + } if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.factoryReset) { if(root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardMetadataDisplay) { if (root.sharedKeycardModule.keyPairStoredOnKeycardIsKnown) { @@ -500,6 +528,7 @@ Item { when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.readingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.migratingKeyPair || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhrase || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPin || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPuk || @@ -517,6 +546,9 @@ Item { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhrase) { return qsTr("Creating new account...") } + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhrase) { + return qsTr("Setting a new Keycard...") + } if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.renamingKeycard) { return qsTr("Renaming keycard...") } @@ -733,7 +765,8 @@ Item { return qsTr("To migrate %1 on to this Keycard, you\nwill need to perform a factory reset first") .arg(root.sharedKeycardModule.keyPairForProcessing.name) } - if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase) { + if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase) { return qsTr("To create a new account on to this Keycard, you\nwill need to perform a factory reset first") } if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard) { @@ -756,12 +789,14 @@ Item { target: title text: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard? qsTr("Keycard locked and already stores keys") : qsTr("Keycard locked") font.pixelSize: Constants.keycard.general.fontSize1 font.weight: Font.Bold color: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard? Theme.palette.directColor1 : Theme.palette.dangerColor1 } @@ -781,6 +816,7 @@ Item { if (root.sharedKeycardModule.keycardData & Constants.predefinedKeycardData.useGeneralMessageForLockedState) { if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard) return qsTr("The Keycard you have inserted is locked,\nyou will need to factory reset it before proceeding") return qsTr("You will need to unlock it before proceeding") @@ -796,6 +832,7 @@ Item { font.pixelSize: Constants.keycard.general.fontSize2 color: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard? Theme.palette.directColor1 : Theme.palette.dangerColor1 } @@ -854,6 +891,7 @@ Item { name: "processing-success" when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateSuccess || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhraseSuccess || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseSuccess || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.unlockKeycardSuccess || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameSuccess || @@ -869,9 +907,13 @@ Item { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhraseSuccess) { return qsTr("New account successfully created") } + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseSuccess) { + return qsTr("Keycard is ready to use!") + } if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess) { if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard) return qsTr("Your Keycard has been reset") return qsTr("Keycard successfully factory reset") @@ -917,6 +959,7 @@ Item { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.factoryResetSuccess) { if (root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycard || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase || root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.createCopyOfAKeycard) return qsTr("You can now create a new key pair on this Keycard") return qsTr("You can now use this Keycard as if it\nwas a brand new empty Keycard") @@ -931,6 +974,7 @@ Item { name: "processing-failure" when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keyPairMigrateFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhraseFailure || + root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPukFailure || root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.changingKeycardPairingCodeFailure || @@ -944,6 +988,9 @@ Item { if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountNewSeedPhraseFailure) { return qsTr("Creating new account failed") } + if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.creatingAccountOldSeedPhraseFailure) { + return qsTr("Setting a Keycard failed") + } if (root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.keycardRenameFailure) { return qsTr("Keycard renaming failed") } @@ -1154,6 +1201,27 @@ Item { target: message text: "" } + }, + State { + name: Constants.keycardSharedState.seedPhraseAlreadyInUse + when: root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.seedPhraseAlreadyInUse + PropertyChanges { + target: title + text: "" + } + PropertyChanges { + target: image + source: "" + pattern: "" + visible: false + } + PropertyChanges { + target: message + text: qsTr("The seed phrase you entered is\ncurrently in use on this device") + font.pixelSize: Constants.keycard.general.fontSize1 + font.weight: Font.Bold + color: Theme.palette.directColor1 + } } ] } diff --git a/ui/imports/shared/popups/keycard/states/ManageAccounts.qml b/ui/imports/shared/popups/keycard/states/ManageAccounts.qml index 0beced1400..ad41881d8f 100644 --- a/ui/imports/shared/popups/keycard/states/ManageAccounts.qml +++ b/ui/imports/shared/popups/keycard/states/ManageAccounts.qml @@ -71,8 +71,8 @@ Item { Connections { target: root.emojiPopup - enabled: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase && - root.sharedKeycardModule.currentState.stateType === Constants.keycardSharedState.manageKeycardAccounts + enabled: root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardNewSeedPhrase || + root.sharedKeycardModule.currentState.flowType === Constants.keycardSharedFlow.setupNewKeycardOldSeedPhrase function onEmojiSelected (emojiText, atCursor) { d.observedAccount.emoji = emojiText diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index d82b024317..18473abc00 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -101,6 +101,7 @@ QtObject { readonly property string factoryReset: "FactoryReset" readonly property string setupNewKeycard: "SetupNewKeycard" readonly property string setupNewKeycardNewSeedPhrase: "SetupNewKeycardNewSeedPhrase" + readonly property string setupNewKeycardOldSeedPhrase: "SetupNewKeycardOldSeedPhrase" readonly property string authentication: "Authentication" readonly property string unlockKeycard: "UnlockKeycard" readonly property string displayKeycardContent: "DisplayKeycardContent" @@ -145,6 +146,7 @@ QtObject { readonly property string selectExistingKeyPair: "SelectExistingKeyPair" readonly property string enterSeedPhrase: "EnterSeedPhrase" readonly property string wrongSeedPhrase: "WrongSeedPhrase" + readonly property string seedPhraseAlreadyInUse: "SeedPhraseAlreadyInUse" readonly property string seedPhraseDisplay: "SeedPhraseDisplay" readonly property string seedPhraseEnterWords: "SeedPhraseEnterWords" readonly property string keyPairMigrateSuccess: "KeyPairMigrateSuccess" @@ -184,6 +186,9 @@ QtObject { readonly property string creatingAccountNewSeedPhrase: "CreatingAccountNewSeedPhrase" readonly property string creatingAccountNewSeedPhraseSuccess: "CreatingAccountNewSeedPhraseSuccess" readonly property string creatingAccountNewSeedPhraseFailure: "CreatingAccountNewSeedPhraseFailure" + readonly property string creatingAccountOldSeedPhrase: "CreatingAccountOldSeedPhrase" + readonly property string creatingAccountOldSeedPhraseSuccess: "CreatingAccountOldSeedPhraseSuccess" + readonly property string creatingAccountOldSeedPhraseFailure: "CreatingAccountOldSeedPhraseFailure" } readonly property QtObject keycardAnimations: QtObject {