From c81dfdc7c7c10f3cb0ae4fd5c36a1c1cb0daafe9 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Fri, 25 Aug 2023 11:05:05 +0200 Subject: [PATCH] feat(@desktop/wallet): account Interaction - move keypair to a keycard Part 1 of: #11737 --- .../profile_section/keycard/io_interface.nim | 2 +- .../main/profile_section/keycard/module.nim | 4 +- .../main/profile_section/keycard/view.nim | 8 +-- .../shared_modules/keycard_popup/module.nim | 16 ++++-- .../wallet_account/service_account.nim | 28 ++++++++++ .../wallet_account/service_keycard.nim | 51 +++++++++++++++++++ ui/app/AppLayouts/Profile/ProfileLayout.qml | 49 ++++++++++++++++++ .../controls/WalletKeyPairDelegate.qml | 2 + .../popups/WalletKeypairAccountMenu.qml | 8 +-- .../Profile/stores/KeycardStore.qml | 4 +- .../AppLayouts/Profile/views/KeycardView.qml | 46 ----------------- .../AppLayouts/Profile/views/WalletView.qml | 6 +++ .../Profile/views/keycard/MainView.qml | 2 +- .../Profile/views/wallet/AccountView.qml | 2 + .../Profile/views/wallet/MainView.qml | 4 ++ vendor/status-go | 2 +- 16 files changed, 170 insertions(+), 64 deletions(-) diff --git a/src/app/modules/main/profile_section/keycard/io_interface.nim b/src/app/modules/main/profile_section/keycard/io_interface.nim index fd675364dd..449638dddb 100644 --- a/src/app/modules/main/profile_section/keycard/io_interface.nim +++ b/src/app/modules/main/profile_section/keycard/io_interface.nim @@ -26,7 +26,7 @@ method onDisplayKeycardSharedModuleFlow*(self: AccessInterface) {.base.} = method onSharedKeycarModuleFlowTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool) {.base.} = raise newException(ValueError, "No implementation available") -method runSetupKeycardPopup*(self: AccessInterface) {.base.} = +method runSetupKeycardPopup*(self: AccessInterface, keyUid: string) {.base.} = raise newException(ValueError, "No implementation available") method runCreateNewKeycardWithNewSeedPhrasePopup*(self: AccessInterface) {.base.} = diff --git a/src/app/modules/main/profile_section/keycard/module.nim b/src/app/modules/main/profile_section/keycard/module.nim index 5288aff9aa..a710eee451 100644 --- a/src/app/modules/main/profile_section/keycard/module.nim +++ b/src/app/modules/main/profile_section/keycard/module.nim @@ -114,11 +114,11 @@ method onSharedKeycarModuleFlowTerminated*(self: Module, lastStepInTheCurrentFlo method onDisplayKeycardSharedModuleFlow*(self: Module) = self.view.emitDisplayKeycardSharedModuleFlow() -method runSetupKeycardPopup*(self: Module) = +method runSetupKeycardPopup*(self: Module, keyUid: string) = self.createSharedKeycardModule() if self.keycardSharedModule.isNil: return - self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.SetupNewKeycard) + self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.SetupNewKeycard, keyUid) method runCreateNewKeycardWithNewSeedPhrasePopup*(self: Module) = self.createSharedKeycardModule() diff --git a/src/app/modules/main/profile_section/keycard/view.nim b/src/app/modules/main/profile_section/keycard/view.nim index cfcd8146ee..26c18714bb 100644 --- a/src/app/modules/main/profile_section/keycard/view.nim +++ b/src/app/modules/main/profile_section/keycard/view.nim @@ -43,11 +43,11 @@ QtObject: return newQVariant() QtProperty[QVariant] keycardSharedModule: read = getKeycardSharedModule - + proc sharedModuleBusy*(self: View) {.signal.} proc emitSharedModuleBusy*(self: View) = self.sharedModuleBusy() - + proc displayKeycardSharedModuleFlow*(self: View) {.signal.} proc emitDisplayKeycardSharedModuleFlow*(self: View) = self.displayKeycardSharedModuleFlow() @@ -56,8 +56,8 @@ QtObject: proc emitDestroyKeycardSharedModuleFlow*(self: View) = self.destroyKeycardSharedModuleFlow() - proc runSetupKeycardPopup*(self: View) {.slot.} = - self.delegate.runSetupKeycardPopup() + proc runSetupKeycardPopup*(self: View, keyUid: string) {.slot.} = + self.delegate.runSetupKeycardPopup(keyUid) proc runCreateNewKeycardWithNewSeedPhrasePopup*(self: View) {.slot.} = self.delegate.runCreateNewKeycardWithNewSeedPhrasePopup() diff --git a/src/app/modules/shared_modules/keycard_popup/module.nim b/src/app/modules/shared_modules/keycard_popup/module.nim index 0b73a448fe..69413c21b7 100644 --- a/src/app/modules/shared_modules/keycard_popup/module.nim +++ b/src/app/modules/shared_modules/keycard_popup/module.nim @@ -450,9 +450,19 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Paths if flowToRun == FlowType.SetupNewKeycard: let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = true, excludePrivateKeyKeypairs = false) - self.view.createKeyPairModel(items) - self.view.setCurrentState(newSelectExistingKeyPairState(flowToRun, nil)) - self.controller.readyToDisplayPopup() + if keyUid.len == 0: + self.view.createKeyPairModel(items) + self.view.setCurrentState(newSelectExistingKeyPairState(flowToRun, nil)) + self.controller.readyToDisplayPopup() + else: + let filteredItems = items.filter(x => x.getKeyUid() == keyUid) + if filteredItems.len != 1: + error "sm_cannot resolve a keypair being migrated" + self.controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) + return + self.setSelectedKeyPair(filteredItems[0]) + self.tmpLocalState = newReadingKeycardState(flowToRun, nil) + self.controller.runLoadAccountFlow() return if flowToRun == FlowType.Authentication: self.controller.connectKeychainSignals() diff --git a/src/app_service/service/wallet_account/service_account.nim b/src/app_service/service/wallet_account/service_account.nim index a8b5160e2e..3a4f172476 100644 --- a/src/app_service/service/wallet_account/service_account.nim +++ b/src/app_service/service/wallet_account/service_account.nim @@ -13,6 +13,33 @@ proc storeKeypair(self: Service, keypair: KeypairDto) = return self.keypairs[keypair.keyUid] = keypair +# replaces only keypair/accounts fields that could be changed +proc replaceKeypair(self: Service, keypair: KeypairDto) = + if keypair.keyUid.len == 0: + error "trying to replace a keypair with empty keyUid" + return + if not self.keypairs.hasKey(keypair.keyUid): + error "trying to replace a non existing keypair" + return + var localKp = self.keypairs[keypair.keyUid] + localKp.name = keypair.name + localKp.lastUsedDerivationIndex = keypair.lastUsedDerivationIndex + localKp.syncedFrom = keypair.syncedFrom + localKp.removed = keypair.removed + localKp.keycards = keypair.keycards + for locAcc in localKp.accounts: + for acc in keypair.accounts: + if cmpIgnoreCase(locAcc.address, acc.address) != 0: + continue + locAcc.name = acc.name + locAcc.colorId = acc.colorId + locAcc.emoji = acc.emoji + locAcc.operable = acc.operable + locAcc.removed = acc.removed + locAcc.prodPreferredChainIds = acc.prodPreferredChainIds + locAcc.testPreferredChainIds = acc.testPreferredChainIds + break + proc storeAccountToKeypair(self: Service, account: WalletAccountDto) = if account.keyUid.len == 0: error "trying to store a keypair related account with empty keyUid" @@ -644,6 +671,7 @@ proc handleKeypair(self: Service, keypair: KeypairDto) = localKp.name = keypair.name localKp.lastUsedDerivationIndex = keypair.lastUsedDerivationIndex localKp.syncedFrom = keypair.syncedFrom + localKp.keycards = keypair.keycards # - first remove removed accounts from the UI let addresses = localKp.accounts.map(a => a.address) for address in addresses: diff --git a/src/app_service/service/wallet_account/service_keycard.nim b/src/app_service/service/wallet_account/service_keycard.nim index b874a8e1aa..4b21c798cb 100644 --- a/src/app_service/service/wallet_account/service_keycard.nim +++ b/src/app_service/service/wallet_account/service_keycard.nim @@ -8,7 +8,16 @@ ) self.threadpool.start(arg) +proc updateLocalKeypairOnKeycardChange(self: Service, keyUid: string) = + var kp: KeypairDto + if keyUid.len > 0: + kp = getKeypairByKeyUidFromDb(keyUid) + if kp.isNil: + return + self.replaceKeypair(kp) + proc emitAddKeycardAddAccountsChange(self: Service, success: bool, keycard: KeycardDto) = + self.updateLocalKeypairOnKeycardChange(keycard.keyUid) let data = KeycardArgs( success: success, keycard: keycard @@ -69,6 +78,7 @@ proc onMigratedAccountsForKeycardRemoved*(self: Service, response: string) {.slo data.keycard = kpJson.toKeycardDto() except Exception as e: error "error handilng migrated keycard response", errDesription=e.msg + self.updateLocalKeypairOnKeycardChange(data.keycard.keyUid) self.events.emit(SIGNAL_KEYCARD_ACCOUNTS_REMOVED, data) proc getAllKnownKeycards*(self: Service): seq[KeycardDto] = @@ -105,6 +115,11 @@ proc isKeycardAccount*(self: Service, account: WalletAccountDto): bool = return keycards.len > 0 proc updateKeycardName*(self: Service, keycardUid: string, name: string): bool = + let kc = self.getKeycardByKeycardUid(keycardUid) + let kp = self.getKeypairByKeyUid(kc.keyUid) + if kp.isNil: + error "there is no known keypair", keyUid=kc.keyUid, procName="updateKeycardName" + return var data = KeycardArgs( success: false, keycard: KeycardDto(keycardUid: keycardUid, keycardName: name) @@ -112,12 +127,20 @@ proc updateKeycardName*(self: Service, keycardUid: string, name: string): bool = try: let response = backend.setKeycardName(keycardUid, name) data.success = responseHasNoErrors("updateKeycardName", response) + for kc in kp.keycards.mitems: + if kc.keycardUid == keycardUid: + kc.keycardName = name + break except Exception as e: error "error: ", procName="updateKeycardName", errName = e.name, errDesription = e.msg self.events.emit(SIGNAL_KEYCARD_NAME_CHANGED, data) return data.success proc setKeycardLocked*(self: Service, keyUid: string, keycardUid: string): bool = + let kp = self.getKeypairByKeyUid(keyUid) + if kp.isNil: + error "there is no known keypair", keyUid=keyUid, procName="setKeycardLocked" + return var data = KeycardArgs( success: false, keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid) @@ -125,12 +148,20 @@ proc setKeycardLocked*(self: Service, keyUid: string, keycardUid: string): bool try: let response = backend.keycardLocked(keycardUid) data.success = responseHasNoErrors("setKeycardLocked", response) + for kc in kp.keycards.mitems: + if kc.keycardUid == keycardUid: + kc.keycardLocked = true + break except Exception as e: error "error: ", procName="setKeycardLocked", errName = e.name, errDesription = e.msg self.events.emit(SIGNAL_KEYCARD_LOCKED, data) return data.success proc setKeycardUnlocked*(self: Service, keyUid: string, keycardUid: string): bool = + let kp = self.getKeypairByKeyUid(keyUid) + if kp.isNil: + error "there is no known keypair", keyUid=keyUid, procName="setKeycardUnlocked" + return var data = KeycardArgs( success: false, keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid) @@ -138,12 +169,21 @@ proc setKeycardUnlocked*(self: Service, keyUid: string, keycardUid: string): boo try: let response = backend.keycardUnlocked(keycardUid) data.success = responseHasNoErrors("setKeycardUnlocked", response) + for kc in kp.keycards.mitems: + if kc.keycardUid == keycardUid: + kc.keycardLocked = false + break except Exception as e: error "error: ", procName="setKeycardUnlocked", errName = e.name, errDesription = e.msg self.events.emit(SIGNAL_KEYCARD_UNLOCKED, data) return data.success proc updateKeycardUid*(self: Service, oldKeycardUid: string, newKeycardUid: string): bool = + let kc = self.getKeycardByKeycardUid(oldKeycardUid) + let kp = self.getKeypairByKeyUid(kc.keyUid) + if kp.isNil: + error "there is no known keypair", keyUid=kc.keyUid, procName="updateKeycardUid" + return var data = KeycardArgs( success: false, oldKeycardUid: oldKeycardUid, @@ -152,6 +192,10 @@ proc updateKeycardUid*(self: Service, oldKeycardUid: string, newKeycardUid: stri try: let response = backend.updateKeycardUID(oldKeycardUid, newKeycardUid) data.success = responseHasNoErrors("updateKeycardUid", response) + for kc in kp.keycards.mitems: + if kc.keycardUid == oldKeycardUid: + kc.keycardUid = newKeycardUid + break except Exception as e: error "error: ", procName="updateKeycardUid", errName = e.name, errDesription = e.msg self.events.emit(SIGNAL_KEYCARD_UID_UPDATED, data) @@ -165,12 +209,18 @@ proc deleteKeycard*(self: Service, keycardUid: string): bool = try: let response = backend.deleteKeycard(keycardUid) data.success = responseHasNoErrors("deleteKeycard", response) + let kc = self.getKeycardByKeycardUid(keycardUid) + self.updateLocalKeypairOnKeycardChange(kc.keyUid) except Exception as e: error "error: ", procName="deleteKeycard", errName = e.name, errDesription = e.msg self.events.emit(SIGNAL_KEYCARD_DELETED, data) return data.success proc deleteAllKeycardsWithKeyUid*(self: Service, keyUid: string): bool = + let kp = self.getKeypairByKeyUid(keyUid) + if kp.isNil: + error "there is no known keypair", keyUid=keyUid, procName="deleteAllKeycardsWithKeyUid" + return var data = KeycardArgs( success: false, keycard: KeycardDto(keyUid: keyUid) @@ -178,6 +228,7 @@ proc deleteAllKeycardsWithKeyUid*(self: Service, keyUid: string): bool = try: let response = backend.deleteAllKeycardsWithKeyUID(keyUid) data.success = responseHasNoErrors("deleteAllKeycardsWithKeyUid", response) + kp.keycards = @[] except Exception as e: error "error: ", procName="deleteAllKeycardsWithKeyUid", errName = e.name, errDesription = e.msg self.events.emit(SIGNAL_ALL_KEYCARDS_DELETED, data) diff --git a/ui/app/AppLayouts/Profile/ProfileLayout.qml b/ui/app/AppLayouts/Profile/ProfileLayout.qml index 16de5ef47a..63fc068a70 100644 --- a/ui/app/AppLayouts/Profile/ProfileLayout.qml +++ b/ui/app/AppLayouts/Profile/ProfileLayout.qml @@ -6,6 +6,7 @@ import utils 1.0 import shared 1.0 import shared.panels 1.0 import shared.stores 1.0 as SharedStores +import shared.popups.keycard 1.0 import AppLayouts.Wallet.controls 1.0 @@ -13,8 +14,10 @@ import "stores" import "popups" import "views" +import StatusQ.Core 0.1 import StatusQ.Layout 0.1 import StatusQ.Controls 0.1 +import StatusQ.Popups.Dialog 0.1 StatusSectionLayout { id: root @@ -334,4 +337,50 @@ StatusSectionLayout { } } } + + Connections { + target: root.store.keycardStore.keycardModule + enabled: profileContainer.currentIndex === Constants.settingsSubsection.wallet || + profileContainer.currentIndex === Constants.settingsSubsection.keycard + + function onDisplayKeycardSharedModuleFlow() { + keycardPopup.active = true + } + function onDestroyKeycardSharedModuleFlow() { + keycardPopup.active = false + } + function onSharedModuleBusy() { + Global.openPopup(sharedModuleBusyPopupComponent) + } + } + + Loader { + id: keycardPopup + active: false + sourceComponent: KeycardPopup { + sharedKeycardModule: root.store.keycardStore.keycardModule.keycardSharedModule + emojiPopup: root.emojiPopup + } + + onLoaded: { + keycardPopup.item.open() + } + } + + Component { + id: sharedModuleBusyPopupComponent + StatusDialog { + id: titleContentDialog + title: qsTr("Status Keycard") + + StatusBaseText { + anchors.fill: parent + font.pixelSize: Constants.keycard.general.fontSize2 + color: Theme.palette.directColor1 + text: qsTr("The Keycard module is still busy, please try again") + } + + standardButtons: Dialog.Ok + } + } } diff --git a/ui/app/AppLayouts/Profile/controls/WalletKeyPairDelegate.qml b/ui/app/AppLayouts/Profile/controls/WalletKeyPairDelegate.qml index da06a6900b..72682fb524 100644 --- a/ui/app/AppLayouts/Profile/controls/WalletKeyPairDelegate.qml +++ b/ui/app/AppLayouts/Profile/controls/WalletKeyPairDelegate.qml @@ -28,6 +28,7 @@ Rectangle { signal runImportViaPrivateKeyFlow() signal runRenameKeypairFlow() signal runRemoveKeypairFlow() + signal runMoveKeypairToKeycardFlow() QtObject { id: d @@ -92,6 +93,7 @@ Rectangle { onRunImportViaPrivateKeyFlow: root.runImportViaPrivateKeyFlow() onRunRenameKeypairFlow: root.runRenameKeypairFlow() onRunRemoveKeypairFlow: root.runRemoveKeypairFlow() + onRunMoveKeypairToKeycardFlow: root.runMoveKeypairToKeycardFlow() } } }, diff --git a/ui/app/AppLayouts/Profile/popups/WalletKeypairAccountMenu.qml b/ui/app/AppLayouts/Profile/popups/WalletKeypairAccountMenu.qml index 5a97af2bf6..282c6bd3d5 100644 --- a/ui/app/AppLayouts/Profile/popups/WalletKeypairAccountMenu.qml +++ b/ui/app/AppLayouts/Profile/popups/WalletKeypairAccountMenu.qml @@ -17,6 +17,7 @@ StatusMenu { signal runImportViaPrivateKeyFlow() signal runRenameKeypairFlow() signal runRemoveKeypairFlow() + signal runMoveKeypairToKeycardFlow() StatusAction { text: enabled? qsTr("Show encrypted QR on device") : "" @@ -33,16 +34,15 @@ StatusMenu { } StatusAction { - text: enabled? root.keyPair.migratedToKeycard? qsTr("Stop using Keycard") : qsTr("Move keys to a Keycard") : "" - enabled: !!root.keyPair && - root.keyPair.operability !== Constants.keypair.operability.nonOperable + text: enabled? root.keyPair.migratedToKeycard? qsTr("Stop using Keycard") : qsTr("Move keypair to a Keycard") : "" + enabled: !!root.keyPair icon.name: !!root.keyPair && root.keyPair.migratedToKeycard? "keycard-crossed" : "keycard" icon.color: Theme.palette.primaryColor1 onTriggered: { if (root.keyPair.migratedToKeycard) console.warn("TODO: stop using Keycard") else - console.warn("TODO: move keys to a Keycard") + root.runMoveKeypairToKeycardFlow() } } diff --git a/ui/app/AppLayouts/Profile/stores/KeycardStore.qml b/ui/app/AppLayouts/Profile/stores/KeycardStore.qml index 050286601a..e6c487aff9 100644 --- a/ui/app/AppLayouts/Profile/stores/KeycardStore.qml +++ b/ui/app/AppLayouts/Profile/stores/KeycardStore.qml @@ -6,8 +6,8 @@ QtObject { property var keycardModule - function runSetupKeycardPopup() { - root.keycardModule.runSetupKeycardPopup() + function runSetupKeycardPopup(keyUid) { + root.keycardModule.runSetupKeycardPopup(keyUid) } function runCreateNewKeycardWithNewSeedPhrasePopup() { diff --git a/ui/app/AppLayouts/Profile/views/KeycardView.qml b/ui/app/AppLayouts/Profile/views/KeycardView.qml index 668bea7e41..0c504baf13 100644 --- a/ui/app/AppLayouts/Profile/views/KeycardView.qml +++ b/ui/app/AppLayouts/Profile/views/KeycardView.qml @@ -5,11 +5,9 @@ import QtQml.Models 2.14 import StatusQ.Core 0.1 import StatusQ.Controls 0.1 -import StatusQ.Popups.Dialog 0.1 import StatusQ.Core.Theme 0.1 import utils 1.0 -import shared.popups.keycard 1.0 import "../stores" import "./keycard" @@ -50,23 +48,6 @@ SettingsContentBase { property string observedKeyUid: "" } - Component { - id: sharedModuleBusyPopupComponent - StatusDialog { - id: titleContentDialog - title: qsTr("Status Keycard") - - StatusBaseText { - anchors.fill: parent - font.pixelSize: Constants.keycard.general.fontSize2 - color: Theme.palette.directColor1 - text: qsTr("The Keycard module is still busy, please try again") - } - - standardButtons: Dialog.Ok - } - } - MainView { Layout.preferredWidth: root.contentWidth keycardStore: root.keycardStore @@ -94,32 +75,5 @@ SettingsContentBase { root.handleBackAction() } } - - Connections { - target: root.keycardStore.keycardModule - - function onDisplayKeycardSharedModuleFlow() { - keycardPopup.active = true - } - function onDestroyKeycardSharedModuleFlow() { - keycardPopup.active = false - } - function onSharedModuleBusy() { - Global.openPopup(sharedModuleBusyPopupComponent) - } - } - - Loader { - id: keycardPopup - active: false - sourceComponent: KeycardPopup { - sharedKeycardModule: root.keycardStore.keycardModule.keycardSharedModule - emojiPopup: root.emojiPopup - } - - onLoaded: { - keycardPopup.item.open() - } - } } } diff --git a/ui/app/AppLayouts/Profile/views/WalletView.qml b/ui/app/AppLayouts/Profile/views/WalletView.qml index db7e0df853..30edea83b4 100644 --- a/ui/app/AppLayouts/Profile/views/WalletView.qml +++ b/ui/app/AppLayouts/Profile/views/WalletView.qml @@ -122,6 +122,9 @@ SettingsContentBase { removeKeypairPopup.accounts= model.keyPair.accounts removeKeypairPopup.active = true } + onRunMoveKeypairToKeycardFlow: { + root.rootStore.keycardStore.runSetupKeycardPopup(model.keyPair.keyUid) + } } NetworksView { @@ -187,6 +190,9 @@ SettingsContentBase { onRunImportMissingKeypairFlow: { root.walletStore.runKeypairImportPopup(keyPair.keyUid, Constants.keypairImportPopup.mode.selectImportMethod) } + onRunMoveKeypairToKeycardFlow: { + root.rootStore.keycardStore.runSetupKeycardPopup(keyPair.keyUid) + } } DappPermissionsView { diff --git a/ui/app/AppLayouts/Profile/views/keycard/MainView.qml b/ui/app/AppLayouts/Profile/views/keycard/MainView.qml index 9085b95687..0ec5e8c693 100644 --- a/ui/app/AppLayouts/Profile/views/keycard/MainView.qml +++ b/ui/app/AppLayouts/Profile/views/keycard/MainView.qml @@ -105,7 +105,7 @@ ColumnLayout { } ] onClicked: { - root.keycardStore.runSetupKeycardPopup() + root.keycardStore.runSetupKeycardPopup("") } } diff --git a/ui/app/AppLayouts/Profile/views/wallet/AccountView.qml b/ui/app/AppLayouts/Profile/views/wallet/AccountView.qml index c330f9669d..3a56f3e911 100644 --- a/ui/app/AppLayouts/Profile/views/wallet/AccountView.qml +++ b/ui/app/AppLayouts/Profile/views/wallet/AccountView.qml @@ -27,6 +27,7 @@ ColumnLayout { signal runRenameKeypairFlow() signal runRemoveKeypairFlow() signal runImportMissingKeypairFlow() + signal runMoveKeypairToKeycardFlow() property var account property var keyPair @@ -307,5 +308,6 @@ ColumnLayout { hasPairedDevices: root.walletStore.walletModule.hasPairedDevices onRunRenameKeypairFlow: root.runRenameKeypairFlow() onRunRemoveKeypairFlow: root.runRemoveKeypairFlow() + onRunMoveKeypairToKeycardFlow: root.runMoveKeypairToKeycardFlow() } } diff --git a/ui/app/AppLayouts/Profile/views/wallet/MainView.qml b/ui/app/AppLayouts/Profile/views/wallet/MainView.qml index a88d1b7c4f..0af56e52fc 100644 --- a/ui/app/AppLayouts/Profile/views/wallet/MainView.qml +++ b/ui/app/AppLayouts/Profile/views/wallet/MainView.qml @@ -28,6 +28,7 @@ Column { signal goToDappPermissionsView() signal runRenameKeypairFlow(var model) signal runRemoveKeypairFlow(var model) + signal runMoveKeypairToKeycardFlow(var model) spacing: 8 @@ -238,6 +239,9 @@ Column { onRunImportViaQrFlow: { root.walletStore.runKeypairImportPopup(model.keyPair.keyUid, Constants.keypairImportPopup.mode.importViaQr) } + onRunMoveKeypairToKeycardFlow: { + root.runMoveKeypairToKeycardFlow(model) + } } } } diff --git a/vendor/status-go b/vendor/status-go index 8425e6d238..3ab312f6d1 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 8425e6d238551431d5a75b7a6e5787e85c3b9d11 +Subproject commit 3ab312f6d17ab509cd233647bab1b0dcb46435af