feature(@desktop/keycard): import or restore a Keycard via a seed phrase

Fixes: #7029
This commit is contained in:
Sale Djenic 2022-12-26 13:52:21 +01:00 committed by saledjenic
parent 8600ef35b3
commit b2cb263d68
44 changed files with 588 additions and 34 deletions

View File

@ -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..."

View File

@ -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

View File

@ -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:

View File

@ -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)
return createState(StateType.CreatingAccountNewSeedPhraseFailure, self.flowType, nil)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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]

View File

@ -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:

View File

@ -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:

View File

@ -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 dont 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) {

View File

@ -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()

View File

@ -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) {

View File

@ -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
}
}
]
}

View File

@ -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

View File

@ -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 {