chore(keycard): sync keycard with the current app state updated
This commit resolves a crash happened due to connection to `SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT` when keycard sync flow was run in the background. Also updated the keycard synchronization process with the current state of the application and is the first step of many which leads towards completion of entire syncing feature.
This commit is contained in:
parent
cf5271cfea
commit
c83794470b
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, sequtils, sugar, chronicles, os, uuids
|
import NimQml, sequtils, chronicles, os, uuids
|
||||||
|
|
||||||
import ../../app_service/service/general/service as general_service
|
import ../../app_service/service/general/service as general_service
|
||||||
import ../../app_service/service/keychain/service as keychain_service
|
import ../../app_service/service/keychain/service as keychain_service
|
||||||
|
@ -32,12 +32,11 @@ import ../../app_service/service/mailservers/service as mailservers_service
|
||||||
import ../../app_service/service/gif/service as gif_service
|
import ../../app_service/service/gif/service as gif_service
|
||||||
import ../../app_service/service/ens/service as ens_service
|
import ../../app_service/service/ens/service as ens_service
|
||||||
import ../../app_service/service/community_tokens/service as tokens_service
|
import ../../app_service/service/community_tokens/service as tokens_service
|
||||||
import ../../app_service/common/account_constants
|
|
||||||
|
|
||||||
|
import ../modules/shared_modules/keycard_popup/module as keycard_shared_module
|
||||||
import ../modules/startup/module as startup_module
|
import ../modules/startup/module as startup_module
|
||||||
import ../modules/main/module as main_module
|
import ../modules/main/module as main_module
|
||||||
import ../core/notifications/notifications_manager
|
import ../core/notifications/notifications_manager
|
||||||
|
|
||||||
import ../../constants as main_constants
|
import ../../constants as main_constants
|
||||||
import ../global/global_singleton
|
import ../global/global_singleton
|
||||||
|
|
||||||
|
@ -107,6 +106,7 @@ type
|
||||||
proc load(self: AppController)
|
proc load(self: AppController)
|
||||||
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController)
|
proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController)
|
||||||
proc buildAndRegisterUserProfile(self: AppController)
|
proc buildAndRegisterUserProfile(self: AppController)
|
||||||
|
proc tryKeycardSyncWithTheAppState(self: AppController)
|
||||||
|
|
||||||
# Startup Module Delegate Interface
|
# Startup Module Delegate Interface
|
||||||
proc startupDidLoad*(self: AppController)
|
proc startupDidLoad*(self: AppController)
|
||||||
|
@ -373,6 +373,7 @@ proc startupDidLoad*(self: AppController) =
|
||||||
self.startupModule.startUpUIRaised()
|
self.startupModule.startUpUIRaised()
|
||||||
|
|
||||||
proc mainDidLoad*(self: AppController) =
|
proc mainDidLoad*(self: AppController) =
|
||||||
|
self.tryKeycardSyncWithTheAppState()
|
||||||
self.startupModule.moveToAppState()
|
self.startupModule.moveToAppState()
|
||||||
self.checkForStoringPasswordToKeychain()
|
self.checkForStoringPasswordToKeychain()
|
||||||
|
|
||||||
|
@ -492,6 +493,7 @@ proc buildAndRegisterUserProfile(self: AppController) =
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
|
singletonInstance.engine.setRootContextProperty("userProfile", self.userProfileVariant)
|
||||||
|
|
||||||
|
proc tryKeycardSyncWithTheAppState(self: AppController) =
|
||||||
############################################################################## store def kc sync with app kc uid
|
############################################################################## store def kc sync with app kc uid
|
||||||
## Onboarding flows sync keycard state after login keypair | (inc. kp store) | update
|
## Onboarding flows sync keycard state after login keypair | (inc. kp store) | update
|
||||||
## `I’m new to Status` -> `Generate new keys` -> na | na | na
|
## `I’m new to Status` -> `Generate new keys` -> na | na | na
|
||||||
|
@ -513,56 +515,19 @@ proc buildAndRegisterUserProfile(self: AppController) =
|
||||||
## `Login` -> if card was unlocked via seed phrase -> no | no | yes
|
## `Login` -> if card was unlocked via seed phrase -> no | no | yes
|
||||||
## `Login` -> `Create replacement Keycard with seed phrase` -> no | yes | no (we don't know which kc is replaced if user has more kc for the same kp)
|
## `Login` -> `Create replacement Keycard with seed phrase` -> no | yes | no (we don't know which kc is replaced if user has more kc for the same kp)
|
||||||
##############################################################################
|
##############################################################################
|
||||||
if singletonInstance.userProfile.getIsKeycardUser():
|
if singletonInstance.userProfile.getIsKeycardUser() or
|
||||||
if self.storeDefaultKeyPair:
|
self.syncKeycardBasedOnAppWalletState:
|
||||||
let allAccounts = self.walletAccountService.fetchAccounts()
|
let data = SharedKeycarModuleArgs(
|
||||||
let defaultWalletAccounts = allAccounts.filter(a =>
|
pin: self.startupModule.getPin(),
|
||||||
a.walletType == WalletTypeDefaultStatusAccount and
|
keyUid: singletonInstance.userProfile.getKeyUid()
|
||||||
a.path == account_constants.PATH_DEFAULT_WALLET and
|
|
||||||
not a.isChat and
|
|
||||||
a.isWallet
|
|
||||||
)
|
)
|
||||||
if defaultWalletAccounts.len == 0:
|
self.statusFoundation.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC, data)
|
||||||
error "default wallet account was not generated"
|
|
||||||
return
|
|
||||||
let defaultWalletAddress = defaultWalletAccounts[0].address
|
|
||||||
let keyPair = KeyPairDto(keycardUid: self.keycardService.getLastReceivedKeycardData().flowEvent.instanceUID,
|
|
||||||
keycardName: displayName,
|
|
||||||
keycardLocked: false,
|
|
||||||
accountsAddresses: @[defaultWalletAddress],
|
|
||||||
keyUid: loggedInAccount.keyUid)
|
|
||||||
discard self.walletAccountService.addMigratedKeyPair(keyPair)
|
|
||||||
if self.syncKeycardBasedOnAppWalletState:
|
|
||||||
let allAccounts = self.walletAccountService.fetchAccounts()
|
|
||||||
let accountsForLoggedInUser = allAccounts.filter(a => a.keyUid == loggedInAccount.keyUid)
|
|
||||||
var keyPair = KeyPairDto(keycardUid: "",
|
|
||||||
keycardName: displayName,
|
|
||||||
keycardLocked: false,
|
|
||||||
accountsAddresses: @[],
|
|
||||||
keyUid: loggedInAccount.keyUid)
|
|
||||||
var activeValidPathsToStoreToAKeycard: seq[string]
|
|
||||||
for acc in accountsForLoggedInUser:
|
|
||||||
activeValidPathsToStoreToAKeycard.add(acc.path)
|
|
||||||
keyPair.accountsAddresses.add(acc.address)
|
|
||||||
self.keycardService.startStoreMetadataFlow(displayName, self.startupModule.getPin(), activeValidPathsToStoreToAKeycard)
|
|
||||||
## sleep for 3 seconds, since that is more than enough to store metadata to a keycard, if the reader is still plugged in
|
|
||||||
## and the card is still inserted, otherwise we just skip that.
|
|
||||||
## At the moment we're not able to sync later keycard without metadata, cause such card doesn't return instance uid for
|
|
||||||
## loaded seed phrase, that's in the notes I am taking for discussion with keycard team. If they are able to provide
|
|
||||||
## instance uid for GetMetadata flow we will be able to use SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC signal for syncing
|
|
||||||
## otherwise we need to handle that way separatelly in `handleKeycardSyncing` of shared module
|
|
||||||
sleep(3000)
|
|
||||||
self.keycardService.cancelCurrentFlow()
|
|
||||||
let (_, kcEvent) = self.keycardService.getLastReceivedKeycardData()
|
|
||||||
if kcEvent.instanceUID.len > 0:
|
|
||||||
keyPair.keycardUid = kcEvent.instanceUID
|
|
||||||
discard self.walletAccountService.addMigratedKeyPair(keyPair)
|
|
||||||
|
|
||||||
if self.changedKeycardUids.len > 0:
|
if self.changedKeycardUids.len > 0:
|
||||||
let oldUid = self.changedKeycardUids[0].oldKcUid
|
let oldUid = self.changedKeycardUids[0].oldKcUid
|
||||||
let newUid = self.changedKeycardUids[^1].newKcUid
|
let newUid = self.changedKeycardUids[^1].newKcUid
|
||||||
discard self.walletAccountService.updateKeycardUid(oldUid, newUid)
|
discard self.walletAccountService.updateKeycardUid(oldUid, newUid)
|
||||||
discard self.walletAccountService.setKeycardUnlocked(loggedInAccount.keyUid, newUid)
|
discard self.walletAccountService.setKeycardUnlocked(singletonInstance.userProfile.getKeyUid(), newUid)
|
||||||
|
|
||||||
proc storeDefaultKeyPairForNewKeycardUser*(self: AppController) =
|
proc storeDefaultKeyPairForNewKeycardUser*(self: AppController) =
|
||||||
self.storeDefaultKeyPair = true
|
self.storeDefaultKeyPair = true
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ../../../../app_service/service/contacts/dto/[contacts, status_update]
|
||||||
import ../../../../app_service/service/devices/dto/[device]
|
import ../../../../app_service/service/devices/dto/[device]
|
||||||
import ../../../../app_service/service/settings/dto/[settings]
|
import ../../../../app_service/service/settings/dto/[settings]
|
||||||
import ../../../../app_service/service/saved_address/[dto]
|
import ../../../../app_service/service/saved_address/[dto]
|
||||||
|
import ../../../../app_service/service/wallet_account/[key_pair_dto]
|
||||||
|
|
||||||
type MessageSignal* = ref object of Signal
|
type MessageSignal* = ref object of Signal
|
||||||
bookmarks*: seq[BookmarkDto]
|
bookmarks*: seq[BookmarkDto]
|
||||||
|
@ -32,6 +33,8 @@ type MessageSignal* = ref object of Signal
|
||||||
clearedHistories*: seq[ClearedHistoryDto]
|
clearedHistories*: seq[ClearedHistoryDto]
|
||||||
verificationRequests*: seq[VerificationRequest]
|
verificationRequests*: seq[VerificationRequest]
|
||||||
savedAddresses*: seq[SavedAddressDto]
|
savedAddresses*: seq[SavedAddressDto]
|
||||||
|
keycards*: seq[KeyPairDto]
|
||||||
|
keycardActions*: seq[KeycardActionDto]
|
||||||
|
|
||||||
type MessageDeliveredSignal* = ref object of Signal
|
type MessageDeliveredSignal* = ref object of Signal
|
||||||
chatId*: string
|
chatId*: string
|
||||||
|
@ -130,5 +133,13 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
|
||||||
for jsonSavedAddress in event["event"]["savedAddresses"]:
|
for jsonSavedAddress in event["event"]["savedAddresses"]:
|
||||||
signal.savedAddresses.add(jsonSavedAddress.toSavedAddressDto())
|
signal.savedAddresses.add(jsonSavedAddress.toSavedAddressDto())
|
||||||
|
|
||||||
|
if event["event"]{"keycards"} != nil:
|
||||||
|
for jsonKc in event["event"]["keycards"]:
|
||||||
|
signal.keycards.add(jsonKc.toKeyPairDto())
|
||||||
|
|
||||||
|
if event["event"]{"keycardActions"} != nil:
|
||||||
|
for jsonKc in event["event"]["keycardActions"]:
|
||||||
|
signal.keycardActions.add(jsonKc.toKeycardActionDto())
|
||||||
|
|
||||||
result = signal
|
result = signal
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,12 @@ proc init*(self: Controller) =
|
||||||
return
|
return
|
||||||
self.delegate.onNewKeycardSet(args.keyPair)
|
self.delegate.onNewKeycardSet(args.keyPair)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_KEYCARDS_SYNCHRONIZED) do(e: Args):
|
||||||
|
let args = KeycardActivityArgs(e)
|
||||||
|
if not args.success:
|
||||||
|
return
|
||||||
|
self.delegate.onKeycardsSynchronized()
|
||||||
|
|
||||||
self.events.on(SIGNAL_KEYCARD_LOCKED) do(e: Args):
|
self.events.on(SIGNAL_KEYCARD_LOCKED) do(e: Args):
|
||||||
let args = KeycardActivityArgs(e)
|
let args = KeycardActivityArgs(e)
|
||||||
self.delegate.onKeycardLocked(args.keyPair.keyUid, args.keyPair.keycardUid)
|
self.delegate.onKeycardLocked(args.keyPair.keyUid, args.keyPair.keycardUid)
|
||||||
|
|
|
@ -66,6 +66,9 @@ method runCreateNewPairingCodePopup*(self: AccessInterface, keyUid: string) {.ba
|
||||||
method onLoggedInUserImageChanged*(self: AccessInterface) {.base.} =
|
method onLoggedInUserImageChanged*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method onKeycardsSynchronized*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onNewKeycardSet*(self: AccessInterface, keyPair: KeyPairDto) {.base.} =
|
method onNewKeycardSet*(self: AccessInterface, keyPair: KeyPairDto) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
|
|
@ -276,6 +276,9 @@ method onLoggedInUserImageChanged*(self: Module) =
|
||||||
return
|
return
|
||||||
self.view.keycardDetailsModel().setImage(singletonInstance.userProfile.getPubKey(), singletonInstance.userProfile.getIcon())
|
self.view.keycardDetailsModel().setImage(singletonInstance.userProfile.getPubKey(), singletonInstance.userProfile.getIcon())
|
||||||
|
|
||||||
|
method onKeycardsSynchronized*(self: Module) =
|
||||||
|
self.buildKeycardList()
|
||||||
|
|
||||||
method onNewKeycardSet*(self: Module, keyPair: KeyPairDto) =
|
method onNewKeycardSet*(self: Module, keyPair: KeyPairDto) =
|
||||||
let walletAccounts = self.controller.getWalletAccounts()
|
let walletAccounts = self.controller.getWalletAccounts()
|
||||||
var mainViewItem = self.view.keycardModel().getItemForKeyUid(keyPair.keyUid)
|
var mainViewItem = self.view.keycardModel().getItemForKeyUid(keyPair.keyUid)
|
||||||
|
|
|
@ -150,6 +150,12 @@ method load*(self: Module) =
|
||||||
return
|
return
|
||||||
self.refreshWalletAccounts()
|
self.refreshWalletAccounts()
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_KEYCARDS_SYNCHRONIZED) do(e: Args):
|
||||||
|
let args = KeycardActivityArgs(e)
|
||||||
|
if not args.success:
|
||||||
|
return
|
||||||
|
self.refreshWalletAccounts()
|
||||||
|
|
||||||
self.controller.init()
|
self.controller.init()
|
||||||
self.view.load()
|
self.view.load()
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ proc disconnectAll*(self: Controller) =
|
||||||
proc delete*(self: Controller) =
|
proc delete*(self: Controller) =
|
||||||
self.disconnectAll()
|
self.disconnectAll()
|
||||||
|
|
||||||
proc init*(self: Controller) =
|
proc init*(self: Controller, fullConnect = true) =
|
||||||
self.connectKeycardReponseSignal()
|
self.connectKeycardReponseSignal()
|
||||||
|
|
||||||
var handlerId = self.events.onWithUUID(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
var handlerId = self.events.onWithUUID(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
||||||
|
@ -176,22 +176,23 @@ proc init*(self: Controller) =
|
||||||
self.delegate.onUserAuthenticated(args.password, args.pin)
|
self.delegate.onUserAuthenticated(args.password, args.pin)
|
||||||
self.connectionIds.add(handlerId)
|
self.connectionIds.add(handlerId)
|
||||||
|
|
||||||
handlerId = self.events.onWithUUID(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
if fullConnect:
|
||||||
let args = KeycardActivityArgs(e)
|
handlerId = self.events.onWithUUID(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||||
self.tmpAddingMigratedKeypairSuccess = args.success
|
let args = KeycardActivityArgs(e)
|
||||||
self.delegate.onSecondaryActionClicked()
|
self.tmpAddingMigratedKeypairSuccess = args.success
|
||||||
self.connectionIds.add(handlerId)
|
self.delegate.onSecondaryActionClicked()
|
||||||
|
self.connectionIds.add(handlerId)
|
||||||
handlerId = self.events.onWithUUID(SIGNAL_CONVERTING_PROFILE_KEYPAIR) do(e: Args):
|
|
||||||
let args = ResultArgs(e)
|
handlerId = self.events.onWithUUID(SIGNAL_CONVERTING_PROFILE_KEYPAIR) do(e: Args):
|
||||||
self.tmpConvertingProfileSuccess = args.success
|
let args = ResultArgs(e)
|
||||||
self.delegate.onSecondaryActionClicked()
|
self.tmpConvertingProfileSuccess = args.success
|
||||||
self.connectionIds.add(handlerId)
|
self.delegate.onSecondaryActionClicked()
|
||||||
|
self.connectionIds.add(handlerId)
|
||||||
|
|
||||||
handlerId = self.events.onWithUUID(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args):
|
handlerId = self.events.onWithUUID(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args):
|
||||||
let arg = TokensPerAccountArgs(e)
|
let arg = TokensPerAccountArgs(e)
|
||||||
self.delegate.onTokensRebuilt(arg.accountsTokens)
|
self.delegate.onTokensRebuilt(arg.accountsTokens)
|
||||||
self.connectionIds.add(handlerId)
|
self.connectionIds.add(handlerId)
|
||||||
|
|
||||||
proc switchToWalletSection*(self: Controller) =
|
proc switchToWalletSection*(self: Controller) =
|
||||||
let data = ActiveSectionChatArgs(sectionId: conf.WALLET_SECTION_ID)
|
let data = ActiveSectionChatArgs(sectionId: conf.WALLET_SECTION_ID)
|
||||||
|
@ -661,11 +662,11 @@ proc setCurrentKeycardStateToUnlocked*(self: Controller, keyUid: string, keycard
|
||||||
if not self.walletAccountService.setKeycardUnlocked(keyUid, keycardUid):
|
if not self.walletAccountService.setKeycardUnlocked(keyUid, keycardUid):
|
||||||
info "updating keycard unlocked state failed", keyUid=keyUid, keycardUid=keycardUid
|
info "updating keycard unlocked state failed", keyUid=keyUid, keycardUid=keycardUid
|
||||||
|
|
||||||
proc updateKeycardName*(self: Controller, keyUid: string, keycardUid: string, keycardName: string): bool =
|
proc updateKeycardName*(self: Controller, keycardUid: string, keycardName: string): bool =
|
||||||
if not serviceApplicable(self.walletAccountService):
|
if not serviceApplicable(self.walletAccountService):
|
||||||
return false
|
return false
|
||||||
if not self.walletAccountService.updateKeycardName(keyUid, keycardUid, keycardName):
|
if not self.walletAccountService.updateKeycardName(keycardUid, keycardName):
|
||||||
info "updating keycard name failed", keyUid=keyUid, keycardUid=keycardUid, keycardName=keycardName
|
info "updating keycard name failed", keycardUid=keycardUid, keycardName=keycardName
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ method executePrePrimaryStateCommand*(self: RenamingKeycardState, controller: Co
|
||||||
let md = controller.getMetadataFromKeycard()
|
let md = controller.getMetadataFromKeycard()
|
||||||
let paths = md.walletAccounts.map(a => a.path)
|
let paths = md.walletAccounts.map(a => a.path)
|
||||||
let name = controller.getKeyPairForProcessing().getName()
|
let name = controller.getKeyPairForProcessing().getName()
|
||||||
self.success = controller.updateKeycardName(controller.getKeyPairForProcessing().getKeyUid(), controller.getKeycardUid(), name)
|
self.success = controller.updateKeycardName(controller.getKeycardUid(), name)
|
||||||
if self.success:
|
if self.success:
|
||||||
controller.runStoreMetadataFlow(name, controller.getPin(), paths)
|
controller.runStoreMetadataFlow(name, controller.getPin(), paths)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import os
|
|
||||||
|
|
||||||
type
|
type
|
||||||
WrongSeedPhraseState* = ref object of State
|
WrongSeedPhraseState* = ref object of State
|
||||||
verifiedSeedPhrase: bool
|
verifiedSeedPhrase: bool
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import NimQml, Tables, strformat, strutils
|
import NimQml, Tables, strformat, strutils
|
||||||
import key_pair_account_item
|
import key_pair_account_item
|
||||||
|
|
||||||
import ../../../../../app_service/common/account_constants
|
import ../../../../../app_service/common/utils
|
||||||
|
|
||||||
export key_pair_account_item
|
export key_pair_account_item
|
||||||
|
|
||||||
|
@ -82,10 +82,8 @@ QtObject:
|
||||||
|
|
||||||
proc containsPathOutOfTheDefaultStatusDerivationTree*(self: KeyPairAccountModel): bool =
|
proc containsPathOutOfTheDefaultStatusDerivationTree*(self: KeyPairAccountModel): bool =
|
||||||
for it in self.items:
|
for it in self.items:
|
||||||
if not it.getPath().startsWith(account_constants.PATH_WALLET_ROOT&"/") or
|
if utils.isPathOutOfTheDefaultStatusDerivationTree(it.getPath()):
|
||||||
it.getPath().count("'") != 3 or
|
return true
|
||||||
it.getPath().count("/") != 5:
|
|
||||||
return true
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc getItemAtIndex*(self: KeyPairAccountModel, index: int): KeyPairAccountItem =
|
proc getItemAtIndex*(self: KeyPairAccountModel, index: int): KeyPairAccountItem =
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, tables, random, strutils, marshal, sequtils, sugar, chronicles
|
import NimQml, tables, random, strutils, sequtils, sugar, chronicles
|
||||||
|
|
||||||
import io_interface
|
import io_interface
|
||||||
import view, controller
|
import view, controller
|
||||||
|
@ -66,10 +66,10 @@ method delete*[T](self: Module[T]) =
|
||||||
self.viewVariant.delete
|
self.viewVariant.delete
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
|
|
||||||
proc init[T](self: Module[T]) =
|
proc init[T](self: Module[T], fullConnect = true) =
|
||||||
if not self.initialized:
|
if not self.initialized:
|
||||||
self.initialized = true
|
self.initialized = true
|
||||||
self.controller.init()
|
self.controller.init(fullConnect)
|
||||||
|
|
||||||
method getModuleAsVariant*[T](self: Module[T]): QVariant =
|
method getModuleAsVariant*[T](self: Module[T]): QVariant =
|
||||||
return self.viewVariant
|
return self.viewVariant
|
||||||
|
@ -241,13 +241,20 @@ proc handleKeycardSyncing[T](self: Module[T]) =
|
||||||
accountsAddresses: @[],
|
accountsAddresses: @[],
|
||||||
keyUid: flowEvent.keyUid)
|
keyUid: flowEvent.keyUid)
|
||||||
let alreadySetKeycards = self.controller.getAllKnownKeycards().filter(kp => kp.keycardUid == flowEvent.instanceUID)
|
let alreadySetKeycards = self.controller.getAllKnownKeycards().filter(kp => kp.keycardUid == flowEvent.instanceUID)
|
||||||
if alreadySetKeycards.len == 1:
|
if alreadySetKeycards.len <= 1:
|
||||||
var accountsToRemove = alreadySetKeycards[0].accountsAddresses
|
var accountsToRemove: seq[string]
|
||||||
|
if alreadySetKeycards.len == 1:
|
||||||
|
accountsToRemove = alreadySetKeycards[0].accountsAddresses
|
||||||
let appAccounts = self.controller.getWalletAccounts()
|
let appAccounts = self.controller.getWalletAccounts()
|
||||||
var activeValidPathsToStoreToAKeycard: seq[string]
|
var activeValidPathsToStoreToAKeycard: seq[string]
|
||||||
|
var containsPathOutOfTheDefaultStatusDerivationTree = false
|
||||||
for appAcc in appAccounts:
|
for appAcc in appAccounts:
|
||||||
if appAcc.keyUid != flowEvent.keyUid:
|
if appAcc.keyUid != flowEvent.keyUid:
|
||||||
continue
|
continue
|
||||||
|
# do not sync if any wallet's account has path out of the default Status derivation tree
|
||||||
|
if utils.isPathOutOfTheDefaultStatusDerivationTree(appAcc.path):
|
||||||
|
containsPathOutOfTheDefaultStatusDerivationTree = true
|
||||||
|
break
|
||||||
activeValidPathsToStoreToAKeycard.add(appAcc.path)
|
activeValidPathsToStoreToAKeycard.add(appAcc.path)
|
||||||
var index = -1
|
var index = -1
|
||||||
var found = false
|
var found = false
|
||||||
|
@ -264,24 +271,25 @@ proc handleKeycardSyncing[T](self: Module[T]) =
|
||||||
# we store to db only accounts we haven't stored before, accounts which are already on a keycard (in metadata)
|
# we store to db only accounts we haven't stored before, accounts which are already on a keycard (in metadata)
|
||||||
# we assume they are already in the db
|
# we assume they are already in the db
|
||||||
kpDto.accountsAddresses.add(appAcc.address)
|
kpDto.accountsAddresses.add(appAcc.address)
|
||||||
if accountsToRemove.len > 0:
|
if not containsPathOutOfTheDefaultStatusDerivationTree:
|
||||||
self.controller.removeMigratedAccountsForKeycard(kpDto.keyUid, kpDto.keycardUid, accountsToRemove)
|
if accountsToRemove.len > 0:
|
||||||
if kpDto.accountsAddresses.len > 0:
|
self.controller.removeMigratedAccountsForKeycard(kpDto.keyUid, kpDto.keycardUid, accountsToRemove)
|
||||||
self.controller.addMigratedKeyPair(kpDto)
|
if kpDto.accountsAddresses.len > 0:
|
||||||
# if all accounts are removed from the app, there is no point in storing empty accounts list to a keycard, cause in that case
|
self.controller.addMigratedKeyPair(kpDto)
|
||||||
# keypair which is on that keycard won't be known to the app, that means keypair was removed from the app
|
# if all accounts are removed from the app, there is no point in storing empty accounts list to a keycard, cause in that case
|
||||||
if activeValidPathsToStoreToAKeycard.len > 0:
|
# keypair which is on that keycard won't be known to the app, that means keypair was removed from the app
|
||||||
## we need to store paths to a keycard if the num of paths in the app and on a keycard is diffrent
|
if activeValidPathsToStoreToAKeycard.len > 0:
|
||||||
## or if the paths are different
|
## we need to store paths to a keycard if the num of paths in the app and on a keycard is diffrent
|
||||||
var storeToKeycard = activeValidPathsToStoreToAKeycard.len != flowEvent.cardMetadata.walletAccounts.len
|
## or if the paths are different
|
||||||
if not storeToKeycard:
|
var storeToKeycard = activeValidPathsToStoreToAKeycard.len != flowEvent.cardMetadata.walletAccounts.len
|
||||||
for wa in flowEvent.cardMetadata.walletAccounts:
|
if not storeToKeycard:
|
||||||
if not utils.arrayContains(activeValidPathsToStoreToAKeycard, wa.path):
|
for wa in flowEvent.cardMetadata.walletAccounts:
|
||||||
storeToKeycard = true
|
if not utils.arrayContains(activeValidPathsToStoreToAKeycard, wa.path):
|
||||||
break
|
storeToKeycard = true
|
||||||
if storeToKeycard:
|
break
|
||||||
self.controller.runStoreMetadataFlow(flowEvent.cardMetadata.name, self.controller.getPin(), activeValidPathsToStoreToAKeycard)
|
if storeToKeycard:
|
||||||
return
|
self.controller.runStoreMetadataFlow(flowEvent.cardMetadata.name, self.controller.getPin(), activeValidPathsToStoreToAKeycard)
|
||||||
|
return
|
||||||
elif alreadySetKeycards.len > 1:
|
elif alreadySetKeycards.len > 1:
|
||||||
error "it's impossible to have more then one keycard with the same uid", keycarUid=flowEvent.instanceUID
|
error "it's impossible to have more then one keycard with the same uid", keycarUid=flowEvent.instanceUID
|
||||||
self.controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
self.controller.terminateCurrentFlow(lastStepInTheCurrentFlow = true)
|
||||||
|
@ -295,7 +303,7 @@ method syncKeycardBasedOnAppState*[T](self: Module[T], keyUid: string, pin: stri
|
||||||
if keyUid.len == 0:
|
if keyUid.len == 0:
|
||||||
debug "cannot sync with the empty keyUid"
|
debug "cannot sync with the empty keyUid"
|
||||||
return
|
return
|
||||||
self.init()
|
self.init(fullConnect = false)
|
||||||
self.controller.setKeyUidWhichIsBeingSyncing(keyUid)
|
self.controller.setKeyUidWhichIsBeingSyncing(keyUid)
|
||||||
self.controller.setPin(pin)
|
self.controller.setPin(pin)
|
||||||
self.controller.setKeycardSyncingInProgress(true)
|
self.controller.setKeycardSyncingInProgress(true)
|
||||||
|
|
|
@ -342,7 +342,7 @@ proc delayStartingApp[T](self: Module[T]) =
|
||||||
## - FlowType.FirstRunOldUserImportSeedPhrase
|
## - FlowType.FirstRunOldUserImportSeedPhrase
|
||||||
## - FlowType.FirstRunOldUserKeycardImport
|
## - FlowType.FirstRunOldUserKeycardImport
|
||||||
## we want to delay app start just to be sure that messages from waku will be received
|
## we want to delay app start just to be sure that messages from waku will be received
|
||||||
self.controller.connectToTimeoutEventAndStratTimer(timeoutInMilliseconds = 10000) # delay for 30 seconds
|
self.controller.connectToTimeoutEventAndStratTimer(timeoutInMilliseconds = 30000) # delay for 30 seconds
|
||||||
|
|
||||||
method startAppAfterDelay*[T](self: Module[T]) =
|
method startAppAfterDelay*[T](self: Module[T]) =
|
||||||
if not self.view.fetchingDataModel().allMessagesLoaded():
|
if not self.view.fetchingDataModel().allMessagesLoaded():
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import json, random, times, strutils, sugar, os, re, chronicles
|
import json, random, times, strutils, sugar, os, re, chronicles
|
||||||
import nimcrypto
|
import nimcrypto
|
||||||
import signing_phrases
|
import signing_phrases, account_constants
|
||||||
|
|
||||||
import ../../constants as main_constants
|
import ../../constants as main_constants
|
||||||
|
|
||||||
|
@ -74,3 +74,10 @@ proc validateLink*(link: string): bool =
|
||||||
link, re"[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)", 0):
|
link, re"[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)", 0):
|
||||||
error "Invalid social link", errDescription = link
|
error "Invalid social link", errDescription = link
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
|
proc isPathOutOfTheDefaultStatusDerivationTree*(path: string): bool =
|
||||||
|
if not path.startsWith(account_constants.PATH_WALLET_ROOT&"/") or
|
||||||
|
path.count("'") != 3 or
|
||||||
|
path.count("/") != 5:
|
||||||
|
return true
|
||||||
|
return false
|
|
@ -140,14 +140,14 @@ type
|
||||||
const addMigratedKeyPairTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
const addMigratedKeyPairTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
let arg = decode[AddMigratedKeyPairTaskArg](argEncoded)
|
let arg = decode[AddMigratedKeyPairTaskArg](argEncoded)
|
||||||
try:
|
try:
|
||||||
let response = backend.addMigratedKeyPair(
|
let response = backend.addMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(
|
||||||
arg.keyPair.keycardUid,
|
arg.keyPair.keycardUid,
|
||||||
arg.keyPair.keycardName,
|
arg.keyPair.keycardName,
|
||||||
arg.keyPair.keyUid,
|
arg.keyPair.keyUid,
|
||||||
arg.keyPair.accountsAddresses,
|
arg.keyPair.accountsAddresses,
|
||||||
arg.password
|
arg.password
|
||||||
)
|
)
|
||||||
let success = responseHasNoErrors("addMigratedKeyPair", response)
|
let success = responseHasNoErrors("addMigratedKeyPairOrAddAccountsIfKeyPairIsAdded", response)
|
||||||
let responseJson = %*{
|
let responseJson = %*{
|
||||||
"success": success,
|
"success": success,
|
||||||
"keyPair": arg.keyPair.toJsonNode()
|
"keyPair": arg.keyPair.toJsonNode()
|
||||||
|
|
|
@ -2,12 +2,23 @@ import json
|
||||||
|
|
||||||
include ../../common/json_utils
|
include ../../common/json_utils
|
||||||
|
|
||||||
const KeycardUid = "keycard-uid"
|
const ParamKeycardUid = "keycard-uid"
|
||||||
const KeycardName = "keycard-name"
|
const ParamKeycardName = "keycard-name"
|
||||||
const KeycardLocked = "keycard-locked"
|
const ParamKeycardLocked = "keycard-locked"
|
||||||
const KeyUid = "key-uid"
|
const ParamKeyUid = "key-uid"
|
||||||
const AccountAddresses = "accounts-addresses"
|
const ParamAccountAddresses = "accounts-addresses"
|
||||||
|
const ParamAction = "action"
|
||||||
|
const ParamOldKeycardUid = "old-keycard-uid"
|
||||||
|
const ParamKeycard = "keycard"
|
||||||
|
|
||||||
|
const KeycardActionKeycardAdded* = "KEYCARD_ADDED"
|
||||||
|
const KeycardActionAccountsAdded* = "ACCOUNTS_ADDED"
|
||||||
|
const KeycardActionKeycardDeleted* = "KEYCARD_DELETED"
|
||||||
|
const KeycardActionAccountsRemoved* = "ACCOUNTS_REMOVED"
|
||||||
|
const KeycardActionLocked* = "LOCKED"
|
||||||
|
const KeycardActionUnlocked* = "UNLOCKED"
|
||||||
|
const KeycardActionUidUpdated* = "UID_UPDATED"
|
||||||
|
const KeycardActionNameChanged* = "NAME_CHANGED"
|
||||||
|
|
||||||
type KeyPairDto* = object
|
type KeyPairDto* = object
|
||||||
keycardUid*: string
|
keycardUid*: string
|
||||||
|
@ -16,23 +27,37 @@ type KeyPairDto* = object
|
||||||
accountsAddresses*: seq[string]
|
accountsAddresses*: seq[string]
|
||||||
keyUid*: string
|
keyUid*: string
|
||||||
|
|
||||||
|
type KeycardActionDto* = object
|
||||||
|
action*: string
|
||||||
|
oldKeycardUid*: string
|
||||||
|
keycard*: KeyPairDto
|
||||||
|
|
||||||
proc toKeyPairDto*(jsonObj: JsonNode): KeyPairDto =
|
proc toKeyPairDto*(jsonObj: JsonNode): KeyPairDto =
|
||||||
result = KeyPairDto()
|
result = KeyPairDto()
|
||||||
discard jsonObj.getProp(KeycardUid, result.keycardUid)
|
discard jsonObj.getProp(ParamKeycardUid, result.keycardUid)
|
||||||
discard jsonObj.getProp(KeycardName, result.keycardName)
|
discard jsonObj.getProp(ParamKeycardName, result.keycardName)
|
||||||
discard jsonObj.getProp(KeycardLocked, result.keycardLocked)
|
discard jsonObj.getProp(ParamKeycardLocked, result.keycardLocked)
|
||||||
discard jsonObj.getProp(KeyUid, result.keyUid)
|
discard jsonObj.getProp(ParamKeyUid, result.keyUid)
|
||||||
|
|
||||||
var jArr: JsonNode
|
var jArr: JsonNode
|
||||||
if(jsonObj.getProp(AccountAddresses, jArr) and jArr.kind == JArray):
|
if(jsonObj.getProp(ParamAccountAddresses, jArr) and jArr.kind == JArray):
|
||||||
for addrObj in jArr:
|
for addrObj in jArr:
|
||||||
result.accountsAddresses.add(addrObj.getStr)
|
result.accountsAddresses.add(addrObj.getStr)
|
||||||
|
|
||||||
|
proc toKeycardActionDto*(jsonObj: JsonNode): KeycardActionDto =
|
||||||
|
result = KeycardActionDto()
|
||||||
|
discard jsonObj.getProp(ParamAction, result.action)
|
||||||
|
discard jsonObj.getProp(ParamOldKeycardUid, result.oldKeycardUid)
|
||||||
|
|
||||||
|
var keycardObj: JsonNode
|
||||||
|
if(jsonObj.getProp("keycard", keycardObj)):
|
||||||
|
result.keycard = toKeyPairDto(keycardObj)
|
||||||
|
|
||||||
proc toJsonNode*(self: KeyPairDto): JsonNode =
|
proc toJsonNode*(self: KeyPairDto): JsonNode =
|
||||||
result = %* {
|
result = %* {
|
||||||
KeycardUid: self.keycardUid,
|
ParamKeycardUid: self.keycardUid,
|
||||||
KeycardName: self.keycardName,
|
ParamKeycardName: self.keycardName,
|
||||||
KeycardLocked: self.keycardLocked,
|
ParamKeycardLocked: self.keycardLocked,
|
||||||
KeyUid: self.keyUid,
|
ParamKeyUid: self.keyUid,
|
||||||
AccountAddresses: self.accountsAddresses
|
ParamAccountAddresses: self.accountsAddresses
|
||||||
}
|
}
|
|
@ -34,7 +34,9 @@ const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_READY* = "walletAccount/derivedAddre
|
||||||
const SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT* = "walletAccount/tokensRebuilt"
|
const SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT* = "walletAccount/tokensRebuilt"
|
||||||
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_DETAILS_FETCHED* = "walletAccount/derivedAddressDetailsFetched"
|
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_DETAILS_FETCHED* = "walletAccount/derivedAddressDetailsFetched"
|
||||||
|
|
||||||
|
const SIGNAL_KEYCARDS_SYNCHRONIZED* = "keycardsSynchronized"
|
||||||
const SIGNAL_NEW_KEYCARD_SET* = "newKeycardSet"
|
const SIGNAL_NEW_KEYCARD_SET* = "newKeycardSet"
|
||||||
|
const SIGNAL_KEYCARD_DELETED* = "keycardDeleted"
|
||||||
const SIGNAL_KEYCARD_ACCOUNTS_REMOVED* = "keycardAccountsRemoved"
|
const SIGNAL_KEYCARD_ACCOUNTS_REMOVED* = "keycardAccountsRemoved"
|
||||||
const SIGNAL_KEYCARD_LOCKED* = "keycardLocked"
|
const SIGNAL_KEYCARD_LOCKED* = "keycardLocked"
|
||||||
const SIGNAL_KEYCARD_UNLOCKED* = "keycardUnlocked"
|
const SIGNAL_KEYCARD_UNLOCKED* = "keycardUnlocked"
|
||||||
|
@ -124,6 +126,8 @@ QtObject:
|
||||||
proc checkRecentHistory*(self: Service)
|
proc checkRecentHistory*(self: Service)
|
||||||
proc checkConnected(self: Service)
|
proc checkConnected(self: Service)
|
||||||
proc startWallet(self: Service)
|
proc startWallet(self: Service)
|
||||||
|
proc handleKeycardActions(self: Service, keycardActions: seq[KeycardActionDto])
|
||||||
|
proc handleKeycardsState(self: Service, keycardsState: seq[KeyPairDto])
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
self.closingApp = true
|
self.closingApp = true
|
||||||
|
@ -227,6 +231,9 @@ QtObject:
|
||||||
if settingsField.name == KEY_CURRENCY:
|
if settingsField.name == KEY_CURRENCY:
|
||||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED, CurrencyUpdated())
|
self.events.emit(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED, CurrencyUpdated())
|
||||||
|
|
||||||
|
self.handleKeycardsState(receivedData.keycards)
|
||||||
|
self.handleKeycardActions(receivedData.keycardActions)
|
||||||
|
|
||||||
self.events.on(SignalType.Wallet.event) do(e:Args):
|
self.events.on(SignalType.Wallet.event) do(e:Args):
|
||||||
var data = WalletSignal(e)
|
var data = WalletSignal(e)
|
||||||
case data.eventType:
|
case data.eventType:
|
||||||
|
@ -614,24 +621,33 @@ QtObject:
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc emitAddKeycardAddAccountsChange(self: Service, success: bool, keyPair: KeyPairDto) =
|
||||||
|
let data = KeycardActivityArgs(
|
||||||
|
success: success,
|
||||||
|
keyPair: keyPair
|
||||||
|
)
|
||||||
|
self.events.emit(SIGNAL_NEW_KEYCARD_SET, data)
|
||||||
|
|
||||||
proc onMigratedKeyPairAdded*(self: Service, response: string) {.slot.} =
|
proc onMigratedKeyPairAdded*(self: Service, response: string) {.slot.} =
|
||||||
var data = KeycardActivityArgs()
|
|
||||||
data.success = false
|
|
||||||
try:
|
try:
|
||||||
let responseObj = response.parseJson
|
let responseObj = response.parseJson
|
||||||
discard responseObj.getProp("success", data.success)
|
var keyPair: KeyPairDto
|
||||||
var kpJson: JsonNode
|
var success = false
|
||||||
if responseObj.getProp("keyPair", kpJson):
|
discard responseObj.getProp("success", success)
|
||||||
data.keyPair = kpJson.toKeyPairDto()
|
if success:
|
||||||
|
var kpJson: JsonNode
|
||||||
|
if responseObj.getProp("keyPair", kpJson):
|
||||||
|
keyPair = kpJson.toKeyPairDto()
|
||||||
|
self.emitAddKeycardAddAccountsChange(success, keyPair)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error handilng migrated keypair response", errDesription=e.msg
|
error "error handilng migrated keypair response", errDesription=e.msg
|
||||||
self.events.emit(SIGNAL_NEW_KEYCARD_SET, data)
|
self.emitAddKeycardAddAccountsChange(success = false, KeyPairDto())
|
||||||
|
|
||||||
proc addMigratedKeyPair*(self: Service, keyPair: KeyPairDto, password = ""): bool =
|
proc addMigratedKeyPair*(self: Service, keyPair: KeyPairDto, password = ""): bool =
|
||||||
# Providing a password corresponding local keystore file will be removed as well, though
|
# Providing a password corresponding local keystore file will be removed as well, though
|
||||||
# in some contexts we just need to add keypair to the db, so password is not needed.
|
# in some contexts we just need to add keypair to the db, so password is not needed.
|
||||||
try:
|
try:
|
||||||
let response = backend.addMigratedKeyPair(
|
let response = backend.addMigratedKeyPairOrAddAccountsIfKeyPairIsAdded(
|
||||||
keyPair.keycardUid,
|
keyPair.keycardUid,
|
||||||
keyPair.keycardName,
|
keyPair.keycardName,
|
||||||
keyPair.keyUid,
|
keyPair.keyUid,
|
||||||
|
@ -640,7 +656,7 @@ QtObject:
|
||||||
)
|
)
|
||||||
result = responseHasNoErrors("addMigratedKeyPair", response)
|
result = responseHasNoErrors("addMigratedKeyPair", response)
|
||||||
if result:
|
if result:
|
||||||
self.events.emit(SIGNAL_NEW_KEYCARD_SET, KeycardActivityArgs(success: true, keyPair: keyPair))
|
self.emitAddKeycardAddAccountsChange(success = true, keyPair)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="addMigratedKeyPair", errName = e.name, errDesription = e.msg
|
error "error: ", procName="addMigratedKeyPair", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
@ -653,18 +669,28 @@ QtObject:
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc emitKeycardRemovedAccountsChange(self: Service, success: bool, keyUid: string, keycardUid: string,
|
||||||
|
removedAccounts: seq[string]) =
|
||||||
|
let data = KeycardActivityArgs(
|
||||||
|
success: success,
|
||||||
|
keyPair: KeyPairDto(keyUid: keyUid, keycardUid: keycardUid, accountsAddresses: removedAccounts)
|
||||||
|
)
|
||||||
|
self.events.emit(SIGNAL_KEYCARD_ACCOUNTS_REMOVED, data)
|
||||||
|
|
||||||
proc onMigratedAccountsForKeycardRemoved*(self: Service, response: string) {.slot.} =
|
proc onMigratedAccountsForKeycardRemoved*(self: Service, response: string) {.slot.} =
|
||||||
var data = KeycardActivityArgs()
|
|
||||||
data.success = false
|
|
||||||
try:
|
try:
|
||||||
let responseObj = response.parseJson
|
let responseObj = response.parseJson
|
||||||
discard responseObj.getProp("success", data.success)
|
var keyPair: KeyPairDto
|
||||||
var kpJson: JsonNode
|
var success = false
|
||||||
if responseObj.getProp("keyPair", kpJson):
|
discard responseObj.getProp("success", success)
|
||||||
data.keyPair = kpJson.toKeyPairDto()
|
if success:
|
||||||
|
var kpJson: JsonNode
|
||||||
|
if responseObj.getProp("keyPair", kpJson):
|
||||||
|
keyPair = kpJson.toKeyPairDto()
|
||||||
|
self.emitKeycardRemovedAccountsChange(success, keyPair.keyUid, keyPair.keycardUid, keyPair.accountsAddresses)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error handilng migrated keypair response", errDesription=e.msg
|
error "error handilng migrated keypair response", errDesription=e.msg
|
||||||
self.events.emit(SIGNAL_KEYCARD_ACCOUNTS_REMOVED, data)
|
self.emitKeycardRemovedAccountsChange(success = false, keyUid = "", keycardUid = "", removedAccounts = @[])
|
||||||
|
|
||||||
proc getAllKnownKeycards*(self: Service): seq[KeyPairDto] =
|
proc getAllKnownKeycards*(self: Service): seq[KeyPairDto] =
|
||||||
try:
|
try:
|
||||||
|
@ -674,6 +700,16 @@ QtObject:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="getAllKnownKeycards", errName = e.name, errDesription = e.msg
|
error "error: ", procName="getAllKnownKeycards", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
proc getKeycardWithKeycardUid*(self: Service, keycardUid: string): KeyPairDto =
|
||||||
|
let allKnownKeycards = self.getAllKnownKeycards()
|
||||||
|
let keycardsWithKeycardUid = allKnownKeycards.filter(kp => kp.keycardUid == keycardUid)
|
||||||
|
if keycardsWithKeycardUid.len == 0:
|
||||||
|
return
|
||||||
|
if keycardsWithKeycardUid.len > 1:
|
||||||
|
error "there are more than one keycard with the same uid", keycardUid=keycardUid
|
||||||
|
return
|
||||||
|
return keycardsWithKeycardUid[0]
|
||||||
|
|
||||||
proc getAllMigratedKeyPairs*(self: Service): seq[KeyPairDto] =
|
proc getAllMigratedKeyPairs*(self: Service): seq[KeyPairDto] =
|
||||||
try:
|
try:
|
||||||
let response = backend.getAllMigratedKeyPairs()
|
let response = backend.getAllMigratedKeyPairs()
|
||||||
|
@ -690,50 +726,68 @@ QtObject:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="getMigratedKeyPairByKeyUid", errName = e.name, errDesription = e.msg
|
error "error: ", procName="getMigratedKeyPairByKeyUid", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
proc updateKeycardName*(self: Service, keyUid: string, keycardUid: string, name: string): bool =
|
proc emitKeycardNameChange(self: Service, keycardUid: string, name: string) =
|
||||||
|
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keycardUid: keycardUid, keycardName: name))
|
||||||
|
self.events.emit(SIGNAL_KEYCARD_NAME_CHANGED, data)
|
||||||
|
|
||||||
|
proc updateKeycardName*(self: Service, keycardUid: string, name: string): bool =
|
||||||
try:
|
try:
|
||||||
let response = backend.setKeycardName(keycardUid, name)
|
let response = backend.setKeycardName(keycardUid, name)
|
||||||
result = responseHasNoErrors("updateKeycardName", response)
|
result = responseHasNoErrors("updateKeycardName", response)
|
||||||
if result:
|
if result:
|
||||||
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keyUid: keyUid, keycardUid: keycardUid, keycardName: name))
|
self.emitKeycardNameChange(keycardUid, name)
|
||||||
self.events.emit(SIGNAL_KEYCARD_NAME_CHANGED, data)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="updateKeycardName", errName = e.name, errDesription = e.msg
|
error "error: ", procName="updateKeycardName", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
proc emitKeycardLockedChange(self: Service, keyUid: string, keycardUid: string) =
|
||||||
|
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keyUid: keyUid, keycardUid: keycardUid))
|
||||||
|
self.events.emit(SIGNAL_KEYCARD_LOCKED, data)
|
||||||
|
|
||||||
proc setKeycardLocked*(self: Service, keyUid: string, keycardUid: string): bool =
|
proc setKeycardLocked*(self: Service, keyUid: string, keycardUid: string): bool =
|
||||||
try:
|
try:
|
||||||
let response = backend.keycardLocked(keycardUid)
|
let response = backend.keycardLocked(keycardUid)
|
||||||
result = responseHasNoErrors("setKeycardLocked", response)
|
result = responseHasNoErrors("setKeycardLocked", response)
|
||||||
if result:
|
if result:
|
||||||
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keyUid: keyUid, keycardUid: keycardUid))
|
self.emitKeycardLockedChange(keyUid, keycardUid)
|
||||||
self.events.emit(SIGNAL_KEYCARD_LOCKED, data)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="setKeycardLocked", errName = e.name, errDesription = e.msg
|
error "error: ", procName="setKeycardLocked", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
proc emitKeycardUnlockedChange(self: Service, keyUid: string, keycardUid: string) =
|
||||||
|
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keyUid: keyUid, keycardUid: keycardUid))
|
||||||
|
self.events.emit(SIGNAL_KEYCARD_UNLOCKED, data)
|
||||||
|
|
||||||
proc setKeycardUnlocked*(self: Service, keyUid: string, keycardUid: string): bool =
|
proc setKeycardUnlocked*(self: Service, keyUid: string, keycardUid: string): bool =
|
||||||
try:
|
try:
|
||||||
let response = backend.keycardUnlocked(keycardUid)
|
let response = backend.keycardUnlocked(keycardUid)
|
||||||
result = responseHasNoErrors("setKeycardUnlocked", response)
|
result = responseHasNoErrors("setKeycardUnlocked", response)
|
||||||
if result:
|
if result:
|
||||||
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keyUid: keyUid, keycardUid: keycardUid))
|
self.emitKeycardUnlockedChange(keyUid, keycardUid)
|
||||||
self.events.emit(SIGNAL_KEYCARD_UNLOCKED, data)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="setKeycardUnlocked", errName = e.name, errDesription = e.msg
|
error "error: ", procName="setKeycardUnlocked", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
proc emitUpdateKeycardUidChange(self: Service, oldKeycardUid: string, newKeycardUid: string) =
|
||||||
|
let data = KeycardActivityArgs(success: true, oldKeycardUid: oldKeycardUid, keyPair: KeyPairDto(keycardUid: newKeycardUid))
|
||||||
|
self.events.emit(SIGNAL_KEYCARD_UID_UPDATED, data)
|
||||||
|
|
||||||
proc updateKeycardUid*(self: Service, oldKeycardUid: string, newKeycardUid: string): bool =
|
proc updateKeycardUid*(self: Service, oldKeycardUid: string, newKeycardUid: string): bool =
|
||||||
try:
|
try:
|
||||||
let response = backend.updateKeycardUID(oldKeycardUid, newKeycardUid)
|
let response = backend.updateKeycardUID(oldKeycardUid, newKeycardUid)
|
||||||
result = responseHasNoErrors("updateKeycardUid", response)
|
result = responseHasNoErrors("updateKeycardUid", response)
|
||||||
if result:
|
if result:
|
||||||
let data = KeycardActivityArgs(success: true, oldKeycardUid: oldKeycardUid, keyPair: KeyPairDto(keycardUid: newKeycardUid))
|
self.emitUpdateKeycardUidChange(oldKeycardUid, newKeycardUid)
|
||||||
self.events.emit(SIGNAL_KEYCARD_UID_UPDATED, data)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="updateKeycardUid", errName = e.name, errDesription = e.msg
|
error "error: ", procName="updateKeycardUid", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
|
proc emitDeleteKeycardChange(self: Service, keycardUid: string) =
|
||||||
|
let data = KeycardActivityArgs(success: true, keyPair: KeyPairDto(keycardUid: keycardUid))
|
||||||
|
self.events.emit(SIGNAL_KEYCARD_DELETED, data)
|
||||||
|
|
||||||
proc deleteKeycard*(self: Service, keycardUid: string): bool =
|
proc deleteKeycard*(self: Service, keycardUid: string): bool =
|
||||||
try:
|
try:
|
||||||
let response = backend.deleteKeycard(keycardUid)
|
let response = backend.deleteKeycard(keycardUid)
|
||||||
return responseHasNoErrors("deleteKeycard", response)
|
result = responseHasNoErrors("deleteKeycard", response)
|
||||||
|
if result:
|
||||||
|
self.emitDeleteKeycardChange(keycardUid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error: ", procName="deleteKeycard", errName = e.name, errDesription = e.msg
|
error "error: ", procName="deleteKeycard", errName = e.name, errDesription = e.msg
|
||||||
return false
|
return false
|
||||||
|
@ -743,4 +797,35 @@ QtObject:
|
||||||
result = self.addOrReplaceWalletAccount(name, address, path, addressAccountIsDerivedFrom, publicKey, keyUid,
|
result = self.addOrReplaceWalletAccount(name, address, path, addressAccountIsDerivedFrom, publicKey, keyUid,
|
||||||
accountType, color, emoji)
|
accountType, color, emoji)
|
||||||
if result.len == 0:
|
if result.len == 0:
|
||||||
self.addNewAccountToLocalStore()
|
self.addNewAccountToLocalStore()
|
||||||
|
|
||||||
|
proc handleKeycardActions(self: Service, keycardActions: seq[KeycardActionDto]) =
|
||||||
|
if keycardActions.len == 0:
|
||||||
|
return
|
||||||
|
for kcAction in keycardActions:
|
||||||
|
if kcAction.action == KeycardActionKeycardAdded or
|
||||||
|
kcAction.action == KeycardActionAccountsAdded:
|
||||||
|
self.emitAddKeycardAddAccountsChange(success = true, kcAction.keycard)
|
||||||
|
elif kcAction.action == KeycardActionKeycardDeleted:
|
||||||
|
self.emitDeleteKeycardChange(kcAction.keycard.keycardUid)
|
||||||
|
elif kcAction.action == KeycardActionAccountsRemoved:
|
||||||
|
let keycard = self.getKeycardWithKeycardUid(kcAction.keycard.keycardUid)
|
||||||
|
self.emitKeycardRemovedAccountsChange(success = true, keycard.keyUid, kcAction.keycard.keycardUid, kcAction.keycard.accountsAddresses)
|
||||||
|
elif kcAction.action == KeycardActionLocked:
|
||||||
|
let keycard = self.getKeycardWithKeycardUid(kcAction.keycard.keycardUid)
|
||||||
|
self.emitKeycardLockedChange(keycard.keyUid, kcAction.keycard.keycardUid)
|
||||||
|
elif kcAction.action == KeycardActionUnlocked:
|
||||||
|
let keycard = self.getKeycardWithKeycardUid(kcAction.keycard.keycardUid)
|
||||||
|
self.emitKeycardUnlockedChange(keycard.keyUid, kcAction.keycard.keycardUid)
|
||||||
|
elif kcAction.action == KeycardActionUidUpdated:
|
||||||
|
self.emitUpdateKeycardUidChange(kcAction.oldKeycardUid, kcAction.keycard.keycardUid)
|
||||||
|
elif kcAction.action == KeycardActionNameChanged:
|
||||||
|
self.emitKeycardNameChange(kcAction.keycard.keycardUid, kcAction.keycard.keycardName)
|
||||||
|
else:
|
||||||
|
error "unsupported action received", action=kcAction.action
|
||||||
|
|
||||||
|
proc handleKeycardsState(self: Service, keycardsState: seq[KeyPairDto]) =
|
||||||
|
if keycardsState.len == 0:
|
||||||
|
return
|
||||||
|
let data = KeycardActivityArgs(success: true)
|
||||||
|
self.events.emit(SIGNAL_KEYCARDS_SYNCHRONIZED, data)
|
|
@ -239,12 +239,12 @@ rpc(fetchMarketValues, "wallet"):
|
||||||
rpc(fetchTokenDetails, "wallet"):
|
rpc(fetchTokenDetails, "wallet"):
|
||||||
symbols: seq[string]
|
symbols: seq[string]
|
||||||
|
|
||||||
rpc(addMigratedKeyPair, "accounts"):
|
rpc(addMigratedKeyPairOrAddAccountsIfKeyPairIsAdded, "accounts"):
|
||||||
keycardUid: string
|
keycardUid: string
|
||||||
keyPairName: string
|
keyPairName: string
|
||||||
keyUid: string
|
keyUid: string
|
||||||
accountAddresses: seq[string]
|
accountAddresses: seq[string]
|
||||||
keyStoreDir: string
|
password: string
|
||||||
|
|
||||||
rpc(removeMigratedAccountsForKeycard, "accounts"):
|
rpc(removeMigratedAccountsForKeycard, "accounts"):
|
||||||
keycardUid: string
|
keycardUid: string
|
||||||
|
|
|
@ -84,6 +84,10 @@ SettingsContentBase {
|
||||||
Layout.preferredWidth: root.contentWidth
|
Layout.preferredWidth: root.contentWidth
|
||||||
keycardStore: root.keycardStore
|
keycardStore: root.keycardStore
|
||||||
keyUid: d.observedKeyUid
|
keyUid: d.observedKeyUid
|
||||||
|
|
||||||
|
onChangeSectionTitle: {
|
||||||
|
root.sectionTitle = title
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
|
@ -18,11 +18,20 @@ ColumnLayout {
|
||||||
property KeycardStore keycardStore
|
property KeycardStore keycardStore
|
||||||
property string keyUid: ""
|
property string keyUid: ""
|
||||||
|
|
||||||
|
signal changeSectionTitle(string title)
|
||||||
|
|
||||||
spacing: Constants.settingsSection.itemSpacing
|
spacing: Constants.settingsSection.itemSpacing
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
property bool collapsed: true
|
property bool collapsed: true
|
||||||
|
|
||||||
|
function checkAndCheckTitleIfNeeded(newKeycardName) {
|
||||||
|
// We change title if there is only a single keycard for a keypair in keycard details view
|
||||||
|
if (root.keycardStore.keycardModule.keycardDetailsModel.count === 1) {
|
||||||
|
root.changeSectionTitle(newKeycardName)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusListView {
|
StatusListView {
|
||||||
|
@ -42,6 +51,10 @@ ColumnLayout {
|
||||||
keyPairIcon: model.keycard.icon
|
keyPairIcon: model.keycard.icon
|
||||||
keyPairImage: model.keycard.image
|
keyPairImage: model.keycard.image
|
||||||
keyPairAccounts: model.keycard.accounts
|
keyPairAccounts: model.keycard.accounts
|
||||||
|
|
||||||
|
onKeycardNameChanged: {
|
||||||
|
d.checkAndCheckTitleIfNeeded(keycardName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit d0cc036d486092262382d45967db11f19d66641e
|
Subproject commit 2d16e7b8910f40070086f3966ce8f9eb55ee8223
|
|
@ -1 +1 @@
|
||||||
Subproject commit b50cfe22ac3802d508e34b0561095c7100f6efa8
|
Subproject commit 5bfafd14e6361c551cfb55b527448de8e4646e83
|
Loading…
Reference in New Issue