fix(@desktop/wallet): review comments applied for keypair rename feature

- labels changed in Figma, updated in the app
- `Show encrypted QR of keypairs on device` is displayed only if needed now,
for this I had to add account/keypair `operability` feature, so far it handles only
displaying a context menu option, later in a separate issue a proper functionality
will be added
- wallet related toast notifications moved to the proper place (`AppMain.qml`, where
actually all notifications should be handled), not in the place where they occurs, we
need to review other notifications as well and move them there
This commit is contained in:
Sale Djenic 2023-07-17 22:06:34 +02:00 committed by saledjenic
parent 6d25a888d3
commit 4b6066c955
19 changed files with 166 additions and 71 deletions

View File

@ -372,6 +372,15 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
communityTokensItems,
)
proc connectForNotificationsOnly[T](self: Module[T]) =
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e:Args):
let args = AccountArgs(e)
self.view.showToastAccountAdded(args.account.name)
self.events.on(SIGNAL_KEYPAIR_NAME_CHANGED) do(e: Args):
let args = KeypairArgs(e)
self.view.showToastKeypairRenamed(args.oldKeypairName, args.keypair.name)
method load*[T](
self: Module[T],
events: EventEmitter,
@ -387,6 +396,7 @@ method load*[T](
singletonInstance.engine.setRootContextProperty("mainModule", self.viewVariant)
self.controller.init()
self.view.load()
self.connectForNotificationsOnly()
var activeSection: SectionItem
var activeSectionId = singletonInstance.localAccountSensitiveSettings.getActiveSection()

View File

@ -20,6 +20,7 @@ proc initItem*(
keyUid: string = "",
keycardAccount: bool = false,
position: int = 0,
operability: string = ""
): Item =
result = Item()
result.WalletAccountItem.setup(name,
@ -29,7 +30,8 @@ proc initItem*(
walletType,
path,
keyUid,
keycardAccount)
keycardAccount,
operability)
result.position = position
result.relatedAccounts = relatedAccounts

View File

@ -60,7 +60,8 @@ method convertWalletAccountDtoToKeyPairAccountItem(self: Module, account: Wallet
colorId = account.colorId,
icon = "",
balance = 0,
balanceFetched = false)
balanceFetched = false,
operability = account.operable)
method createKeypairItems*(self: Module, walletAccounts: seq[WalletAccountDto]): seq[KeyPairItem] =
var keyPairItems = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,

View File

@ -101,7 +101,7 @@ QtObject:
read = getEphemeralNotificationModel
notify = ephemeralNotificationModelChanged
proc displayEphemeralNotification*(self: View, title: string, subTitle: string, icon: string, loading: bool,
proc displayEphemeralNotification*(self: View, title: string, subTitle: string, icon: string, loading: bool,
ephNotifType: int, url: string) {.slot.} =
self.delegate.displayEphemeralNotification(title, subTitle, icon, loading, ephNotifType, url)
@ -253,7 +253,7 @@ QtObject:
proc activateStatusDeepLink*(self: View, statusDeepLink: string) {.slot.} =
self.delegate.activateStatusDeepLink(statusDeepLink)
proc displayKeycardSharedModuleFlow*(self: View) {.signal.}
proc emitDisplayKeycardSharedModuleFlow*(self: View) =
self.displayKeycardSharedModuleFlow()
@ -262,11 +262,15 @@ QtObject:
proc emitDestroyKeycardSharedModuleFlow*(self: View) =
self.destroyKeycardSharedModuleFlow()
proc windowActivated*(self: View) {.slot.} =
proc windowActivated*(self: View) {.slot.} =
self.delegate.windowActivated()
proc windowDeactivated*(self: View) {.slot.} =
proc windowDeactivated*(self: View) {.slot.} =
self.delegate.windowDeactivated()
proc setCommunityIdToSpectate*(self: View, communityId: string) {.slot.} =
proc setCommunityIdToSpectate*(self: View, communityId: string) {.slot.} =
self.delegate.setCommunityIdToSpectate(communityId)
## Signals for in app (ephemeral) notifications
proc showToastAccountAdded*(self: View, name: string) {.signal.}
proc showToastKeypairRenamed*(self: View, oldName: string, newName: string) {.signal.}

View File

@ -181,7 +181,6 @@ method load*(self: Module) =
let args = AccountArgs(e)
self.setTotalCurrencyBalance()
self.filter.setAddress(args.account.address)
self.view.showToastAccountAdded(args.account.name)
self.notifyFilterChanged()
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
let args = AccountArgs(e)

View File

@ -30,8 +30,6 @@ QtObject:
proc load*(self: View) =
self.delegate.viewDidLoad()
proc showToastAccountAdded*(self: View, name: string) {.signal.}
proc updateCurrency*(self: View, currency: string) {.slot.} =
self.delegate.updateCurrency(currency)
proc getCurrentCurrency(self: View): string {.slot.} =

View File

@ -39,7 +39,8 @@ proc buildKeyPairsList*(keypairs: seq[KeypairDto], excludeAlreadyMigratedPairs:
var icon = ""
if acc.emoji.len == 0:
icon = "wallet"
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId, icon, balance = 0.0))
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId,
icon, balance = 0.0, balanceFetched = true, operability = acc.operable))
items.insert(item, 0) # Status Account must be at first place
continue
if kp.keypairType == KeypairTypeSeed:
@ -57,7 +58,8 @@ proc buildKeyPairsList*(keypairs: seq[KeypairDto], excludeAlreadyMigratedPairs:
var icon = ""
if acc.emoji.len == 0:
icon = "wallet"
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId, icon, balance = 0.0))
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId,
icon, balance = 0.0, balanceFetched = true, operability = acc.operable))
items.add(item)
continue
if kp.keypairType == KeypairTypeKey:
@ -77,7 +79,8 @@ proc buildKeyPairsList*(keypairs: seq[KeypairDto], excludeAlreadyMigratedPairs:
var icon = ""
if acc.emoji.len == 0:
icon = "wallet"
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId, icon, balance = 0.0))
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId,
icon, balance = 0.0, balanceFetched = true, operability = acc.operable))
items.add(item)
continue
if items.len == 0:

View File

@ -34,7 +34,6 @@ proc walletAccountToRelatedAccountItem*(w: WalletAccountDto) : related_account_i
)
proc walletAccountToWalletSettingsAccountsItem*(w: WalletAccountDto, keycardAccount: bool): wallet_settings_accounts_item.Item =
discard
let relatedAccounts = related_accounts_model.newModel()
if w.isNil:
return wallet_settings_accounts_item.initItem()
@ -52,6 +51,7 @@ proc walletAccountToWalletSettingsAccountsItem*(w: WalletAccountDto, keycardAcco
w.keyUid,
keycardAccount,
w.position,
w.operable
)
proc walletAccountToWalletAccountsItem*(w: WalletAccountDto, keycardAccount: bool, enabledChainIds: seq[int], currency: string,

View File

@ -1,4 +1,7 @@
import NimQml, strformat
import app_service/service/wallet_account/dto as wa_dto
export wa_dto
QtObject:
type KeyPairAccountItem* = ref object of QObject
@ -6,6 +9,7 @@ QtObject:
path: string
address: string
pubKey: string
operability: string
emoji: string
colorId: string
icon: string
@ -16,7 +20,7 @@ QtObject:
self.QObject.delete
proc newKeyPairAccountItem*(name = "", path = "", address = "", pubKey = "", emoji = "", colorId = "", icon = "",
balance = 0.0, balanceFetched = true): KeyPairAccountItem =
balance = 0.0, balanceFetched = true, operability = wa_dto.AccountFullyOperable): KeyPairAccountItem =
new(result, delete)
result.QObject.setup
result.name = name
@ -28,6 +32,7 @@ QtObject:
result.icon = icon
result.balance = balance
result.balanceFetched = balanceFetched
result.operability = operability
proc `$`*(self: KeyPairAccountItem): string =
result = fmt"""KeyPairAccountItem[
@ -86,6 +91,17 @@ QtObject:
write = setPubKey
notify = pubKeyChanged
proc operabilityChanged*(self: KeyPairAccountItem) {.signal.}
proc getOperability*(self: KeyPairAccountItem): string {.slot.} =
return self.operability
proc setOperability*(self: KeyPairAccountItem, value: string) {.slot.} =
self.operability = value
self.operabilityChanged()
QtProperty[string] operability:
read = getOperability
write = setOperability
notify = operabilityChanged
proc emojiChanged*(self: KeyPairAccountItem) {.signal.}
proc getEmoji*(self: KeyPairAccountItem): string {.slot.} =
return self.emoji

View File

@ -124,8 +124,13 @@ QtObject:
self.items[i].setEmoji(emoji)
return
proc updateOperabilityForAddress*(self: KeyPairAccountModel, address: string, operability: string) =
for i in 0 ..< self.items.len:
if cmpIgnoreCase(self.items[i].getAddress(), address) == 0:
self.items[i].setOperability(operability)
proc setBalanceForAddress*(self: KeyPairAccountModel, address: string, balance: float) =
for i in 0 ..< self.items.len:
if cmpIgnoreCase(self.items[i].getAddress(), address) == 0:
self.items[i].setBalance(balance)

View File

@ -1,4 +1,4 @@
import NimQml, strformat
import NimQml, strformat, sequtils, sugar
import keypair_account_model
export keypair_account_model
@ -23,6 +23,7 @@ QtObject:
derivedFrom: string
lastUsedDerivationIndex: int
migratedToKeycard: bool
operability: string
accounts: KeyPairAccountModel
observedAccount: KeyPairAccountItem
@ -79,6 +80,7 @@ QtObject:
derivedFrom: {self.derivedFrom},
lastUsedDerivationIndex: {self.lastUsedDerivationIndex},
migratedToKeycard: {self.migratedToKeycard},
operability: {self.operability},
accounts: {$self.accounts}
]"""
@ -192,6 +194,19 @@ QtObject:
write = setMigratedToKeycard
notify = migratedToKeycardChanged
proc operabilityChanged*(self: KeyPairItem) {.signal.}
proc getOperability*(self: KeyPairItem): string {.slot.} =
let items = self.accounts.getItems()
if items.any(x => x.getOperability() == AccountNonOperable):
return AccountNonOperable
if items.any(x => x.getOperability() == AccountPartiallyOperable):
return AccountPartiallyOperable
return AccountFullyOperable
QtProperty[string] operability:
read = getOperability
notify = operabilityChanged
proc observedAccountChanged*(self: KeyPairItem) {.signal.}
proc getObservedAccountAsVariant*(self: KeyPairItem): QVariant {.slot.} =
return newQVariant(self.observedAccount)
@ -204,7 +219,6 @@ QtObject:
proc setLastAccountAsObservedAccount(self: KeyPairItem) =
let index = self.accounts.getCount() - 1
self.setAccountAtIndexAsObservedAccount(index)
proc getAccountsModel*(self: KeyPairItem): KeyPairAccountModel =
return self.accounts
proc getAccountsAsVariant*(self: KeyPairItem): QVariant {.slot.} =
@ -214,15 +228,19 @@ QtObject:
proc removeAccountAtIndex*(self: KeyPairItem, index: int) {.slot.} =
self.accounts.removeItemAtIndex(index)
self.setLastAccountAsObservedAccount()
self.operabilityChanged()
proc removeAccountByAddress*(self: KeyPairItem, address: string) {.slot.} =
self.accounts.removeItemByAddress(address)
self.setLastAccountAsObservedAccount()
self.operabilityChanged()
proc addAccount*(self: KeyPairItem, item: KeyPairAccountItem) =
self.accounts.addItem(item)
self.setLastAccountAsObservedAccount()
self.operabilityChanged()
proc setAccounts*(self: KeyPairItem, items: seq[KeyPairAccountItem]) =
self.accounts.setItems(items)
self.setLastAccountAsObservedAccount()
self.operabilityChanged()
proc containsAccountAddress*(self: KeyPairItem, address: string): bool =
return self.accounts.containsAccountAddress(address)
proc containsAccountPath*(self: KeyPairItem, path: string): bool =
@ -233,6 +251,9 @@ QtObject:
self.accounts.updateDetailsForAddressIfTheyAreSet(address, name, colorId, emoji)
proc setBalanceForAddress*(self: KeyPairItem, address: string, balance: float) =
self.accounts.setBalanceForAddress(address, balance)
proc updateOperabilityForAccountWithAddress*(self: KeyPairItem, address: string, operability: string) =
self.accounts.updateOperabilityForAddress(address, operability)
self.operabilityChanged()
proc setItem*(self: KeyPairItem, item: KeyPairItem) =
self.setKeyUid(item.getKeyUid())

View File

@ -1,4 +1,7 @@
import NimQml, strformat
import app_service/service/wallet_account/dto as wa_dto
export wa_dto
QtObject:
type WalletAccountItem* = ref object of QObject
@ -10,6 +13,7 @@ QtObject:
path: string
keyUid: string
keycardAccount: bool
operability: string
proc setup*(self: WalletAccountItem,
name: string = "",
@ -19,7 +23,8 @@ QtObject:
walletType: string = "",
path: string = "",
keyUid: string = "",
keycardAccount: bool = false
keycardAccount: bool = false,
operability: string = wa_dto.AccountFullyOperable
) =
self.QObject.setup
self.name = name
@ -115,3 +120,13 @@ QtObject:
notify = keycardAccountChanged
proc operabilityChanged*(self: WalletAccountItem) {.signal.}
proc getOperability*(self: WalletAccountItem): string {.slot.} =
return self.operability
proc setOperability*(self: WalletAccountItem, value: string) {.slot.} =
self.operability = value
self.operabilityChanged()
QtProperty[string] operability:
read = getOperability
write = setOperability
notify = operabilityChanged

View File

@ -41,7 +41,7 @@ method executePreSecondaryStateCommand*(self: WrongPinState, controller: Control
self.flowType == FlowType.ChangePairingCode or
self.flowType == FlowType.CreateCopyOfAKeycard:
if controller.getPin().len == PINLengthForStatusApp:
controller.enterKeycardPin(controller.getPin())
controller.enterKeycardPin(controller.getPin())
if self.flowType == FlowType.Authentication:
controller.setUsePinFromBiometrics(false)
controller.tryToObtainDataFromKeychain()
@ -61,13 +61,13 @@ method executeCancelCommand*(self: WrongPinState, controller: Controller) =
self.flowType == FlowType.CreateCopyOfAKeycard:
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
let state = ensureReaderAndCardPresence(self, keycardFlowType, keycardEvent, controller)
if not state.isNil:
return state
if self.flowType == FlowType.FactoryReset:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -75,7 +75,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -84,7 +84,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.SetupNewKeycard:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -92,7 +92,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -101,7 +101,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -109,7 +109,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -118,7 +118,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -126,7 +126,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -135,7 +135,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ImportFromKeycard:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -143,7 +143,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -160,22 +160,22 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
item.setName(keycardEvent.cardMetadata.name)
item.setIcon("keycard")
item.setPairType(KeyPairType.SeedImport.int)
item.addAccount(newKeyPairAccountItem(name = "",
path = accountItem.getPath(),
item.addAccount(newKeyPairAccountItem(name = "",
path = accountItem.getPath(),
address = accountItem.getAddress(),
pubKey = accountItem.getPubKey()
)) # name and other params will be set by the user during the flow
controller.setKeyPairForProcessing(item)
controller.setKeyPairForProcessing(item)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.Authentication:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
if keycardEvent.pinRetries > 0:
return self
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
@ -184,7 +184,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
return nil
if self.flowType == FlowType.DisplayKeycardContent:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -192,7 +192,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -201,7 +201,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.RenameKeycard:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -209,7 +209,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
@ -218,7 +218,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPin:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -226,7 +226,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
@ -235,7 +235,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ChangeKeycardPuk:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -243,7 +243,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
@ -252,7 +252,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
if keycardEvent.error == ErrorChangingCredentials:
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.ChangePairingCode:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -260,7 +260,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.HideKeyPair, add = true))
@ -270,7 +270,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return createState(StateType.PinVerified, self.flowType, nil)
if self.flowType == FlowType.CreateCopyOfAKeycard:
if isPredefinedKeycardDataFlagSet(controller.getKeycardData(), PredefinedKeycardData.CopyFromAKeycardPartDone):
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
@ -278,7 +278,7 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
return self
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.DisableSeedPhraseForUnlock, add = true))
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
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))
@ -287,14 +287,14 @@ method resolveKeycardNextState*(self: WrongPinState, keycardFlowType: string, ke
controller.setMetadataFromKeycard(keycardEvent.cardMetadata)
return createState(StateType.PinVerified, self.flowType, nil)
else:
if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
if keycardEvent.pinRetries > 0:
return self
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueEnterPUK and
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
return createState(StateType.MaxPinRetriesReached, self.flowType, nil)

View File

@ -567,7 +567,7 @@ proc buildKeyPairItemBasedOnCardMetadata[T](self: Module[T], cardMetadata: CardM
if acc.emoji.len == 0:
icon = "wallet"
result.item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId, icon,
balance = 0.0, balanceFetched = true))
balance = 0.0, balanceFetched = true, operability = acc.operable))
# handle unknown accounts
var unknownAccountNumber = 0
for cardAcc in cardMetadata.walletAccounts:

View File

@ -79,6 +79,7 @@ type AccountArgs* = ref object of Args
type KeypairArgs* = ref object of Args
keypair*: KeypairDto
oldKeypairName*: string
type KeycardArgs* = ref object of Args
success*: bool
@ -578,6 +579,9 @@ QtObject:
proc updateKeypairName*(self: Service, keyUid: string, name: string) =
try:
let keypair = self.getKeypairByKeyUid(keyUid)
if keypair.isNil:
return
let response = backend.updateKeypairName(keyUid, name)
if not response.error.isNil:
error "status-go error", procName="updateKeypairName", errCode=response.error.code, errDesription=response.error.message
@ -588,7 +592,8 @@ QtObject:
keypair: KeypairDto(
keyUid: keyUid,
name: name
)
),
oldKeypairName: keypair.name
)
)
except Exception as e:

View File

@ -39,7 +39,7 @@ Rectangle {
width: parent.width
StatusListItem {
Layout.fillWidth: true
title: d.isWatchOnly ? qsTr("Watch only") : model.keyPair.name
title: d.isWatchOnly ? qsTr("Watched addresses") : model.keyPair.name
statusListItemSubTitle.textFormat: Qt.RichText
titleTextIcon: model.keyPair.migratedToKeycard ? "keycard": ""
subTitle: d.isWatchOnly ? "" : d.isProfileKeypair ?
@ -79,8 +79,10 @@ Rectangle {
}
StatusAction {
text: enabled? qsTr("Show encrypted QR of keys on device") : ""
enabled: !d.isProfileKeypair
text: enabled? qsTr("Show encrypted QR of keypairs on device") : ""
enabled: !d.isProfileKeypair &&
!model.keyPair.migratedToKeycard &&
!model.keyPair.operability === Constants.keypair.operability.nonOperable
icon.name: "qr"
icon.color: Theme.palette.primaryColor1
onTriggered: {
@ -116,7 +118,7 @@ Rectangle {
}
StatusAction {
text: enabled? qsTr("Remove master keys and associated accounts") : ""
text: enabled? qsTr("Remove keypair and associated accounts") : ""
enabled: !d.isProfileKeypair
type: StatusAction.Type.Danger
icon.name: "delete"

View File

@ -77,7 +77,7 @@ Item {
backButtonName: RootStore.backButtonName
notificationCount: activityCenterStore.unreadNotificationsCount
hasUnseenNotifications: activityCenterStore.hasUnseenNotifications
onNotificationButtonClicked: Global.openActivityCenterPopup()
onBackButtonClicked: {
rightPanelStackView.currentItem.resetStack();
@ -146,18 +146,4 @@ Item {
anchors.centerIn: parent
}
}
Connections {
target: RootStore.walletSectionInst
function onShowToastAccountAdded(name: string) {
Global.displayToastMessage(
qsTr("\"%1\" successfuly added").arg(name),
"",
"check-circle",
false,
Constants.ephemeralNotificationType.success,
""
)
}
}
}

View File

@ -94,6 +94,28 @@ Item {
function onOpenActivityCenter() {
d.openActivityCenterPopup()
}
function onShowToastAccountAdded(name: string) {
Global.displayToastMessage(
qsTr("\"%1\" successfuly added").arg(name),
"",
"check-circle",
false,
Constants.ephemeralNotificationType.success,
""
)
}
function onShowToastKeypairRenamed(oldName: string, newName: string) {
Global.displayToastMessage(
qsTr("You successfully renamed your keypair\nfrom \"%1\" to \"%2\"").arg(oldName).arg(newName),
"",
"check-circle",
false,
Constants.ephemeralNotificationType.success,
""
)
}
}
QtObject {

View File

@ -469,6 +469,12 @@ QtObject {
readonly property QtObject keypair: QtObject {
readonly property int nameLengthMax: 20
readonly property int nameLengthMin: 5
readonly property QtObject operability: QtObject {
readonly property string nonOperable: "no" // an account is non operable it is not a keycard account and there is no keystore file for it and no keystore file for the address it is derived from
readonly property string partiallyOperable: "partially" // an account is partially operable if it is not a keycard account and there is created keystore file for the address it is derived from
readonly property string fullyOperable: "fully" // an account is fully operable if it is not a keycard account and there is a keystore file for it
}
}
readonly property QtObject validators: QtObject {