refactor: use create/restore/login status-go endpoitns for keycard (#15090)

* chore: remove unused storeDefaultKeyPair

* chore: added CreateAccount keycard parameters

* chore: remove unused newKeycard argument

* chore: create keycard account with ImportAccountAndLogin endpoint

* fix: remove keycardWhisperPrivateKey CreateAccount parameter

* feat: use LoginAccount endpoint for keycard

* fix: use CreateAccount RootDataDir instead of BackupDisabledDataDir

* fix: use loginAccountKeycard instead of loginAccountKeycardUsingSeedPhrase

* fix_: use `login` instead of `loginLocalPairingAccount` an `loginAccountKeycard`

* chore: refactor scheduling reencrpytion

* fix: FirstRunOldUserKeycardImport

* chore: improve code readability

* feat: use RestoreAccountAndLogin endpoint for keycard

* update status-go
This commit is contained in:
Igor Sirotin 2024-06-26 14:12:39 +02:00 committed by GitHub
parent 8cca2664e4
commit c8bc68b96c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 324 additions and 813 deletions

View File

@ -50,7 +50,6 @@ logScope:
type type
AppController* = ref object of RootObj AppController* = ref object of RootObj
storeDefaultKeyPair: bool
syncKeycardBasedOnAppWalletState: bool syncKeycardBasedOnAppWalletState: bool
applyKeycardReplacement: bool applyKeycardReplacement: bool
changedKeycardUids: seq[tuple[oldKcUid: string, newKcUid: string]] # used in case user unlocked keycard during onboarding using seed phrase changedKeycardUids: seq[tuple[oldKcUid: string, newKcUid: string]] # used in case user unlocked keycard during onboarding using seed phrase
@ -120,7 +119,6 @@ proc userLoggedIn*(self: AppController): string
proc appReady*(self: AppController) proc appReady*(self: AppController)
proc logout*(self: AppController) proc logout*(self: AppController)
proc finishAppLoading*(self: AppController) proc finishAppLoading*(self: AppController)
proc storeDefaultKeyPairForNewKeycardUser*(self: AppController)
proc syncKeycardBasedOnAppWalletStateAfterLogin*(self: AppController) proc syncKeycardBasedOnAppWalletStateAfterLogin*(self: AppController)
proc applyKeycardReplacementAfterLogin*(self: AppController) proc applyKeycardReplacementAfterLogin*(self: AppController)
proc addToKeycardUidPairsToCheckForAChangeAfterLogin*(self: AppController, oldKeycardUid: string, newKeycardUid: string) proc addToKeycardUidPairsToCheckForAChangeAfterLogin*(self: AppController, oldKeycardUid: string, newKeycardUid: string)
@ -146,7 +144,6 @@ proc connect(self: AppController) =
proc newAppController*(statusFoundation: StatusFoundation): AppController = proc newAppController*(statusFoundation: StatusFoundation): AppController =
result = AppController() result = AppController()
result.storeDefaultKeyPair = false
result.syncKeycardBasedOnAppWalletState = false result.syncKeycardBasedOnAppWalletState = false
result.applyKeycardReplacement = false result.applyKeycardReplacement = false
result.statusFoundation = statusFoundation result.statusFoundation = statusFoundation
@ -593,9 +590,6 @@ proc applyNecessaryActionsAfterLoggingIn(self: AppController) =
discard self.walletAccountService.updateKeycardUid(oldUid, newUid) discard self.walletAccountService.updateKeycardUid(oldUid, newUid)
discard self.walletAccountService.setKeycardUnlocked(singletonInstance.userProfile.getKeyUid(), newUid) discard self.walletAccountService.setKeycardUnlocked(singletonInstance.userProfile.getKeyUid(), newUid)
proc storeDefaultKeyPairForNewKeycardUser*(self: AppController) =
self.storeDefaultKeyPair = true
proc syncKeycardBasedOnAppWalletStateAfterLogin*(self: AppController) = proc syncKeycardBasedOnAppWalletStateAfterLogin*(self: AppController) =
self.syncKeycardBasedOnAppWalletState = true self.syncKeycardBasedOnAppWalletState = true

View File

@ -75,9 +75,6 @@ QtObject:
return "0" return "0"
return $stint.fromHex(StUint[256], value) return $stint.fromHex(StUint[256], value)
proc generateAlias*(self: Utils, pk: string): string {.slot.} =
return generateAliasFromPk(pk)
proc readTextFile*(self: Utils, filepath: string): string {.slot.} = proc readTextFile*(self: Utils, filepath: string): string {.slot.} =
try: try:
return readFile(filepath) return readFile(filepath)

View File

@ -80,4 +80,4 @@ method resolveKeycardNextState*(self: RepeatPinState, keycardFlowType: string, k
return createState(StateType.MaxPukRetriesReached, self.flowType, nil) return createState(StateType.MaxPukRetriesReached, self.flowType, nil)
if keycardFlowType == ResponseTypeValueKeycardFlowResult: if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setPukValid(true) controller.setPukValid(true)
return createState(StateType.PinSet, self.flowType, nil) return createState(StateType.PinSet, self.flowType, nil)

View File

@ -22,7 +22,7 @@ logScope:
type ProfileImageDetails = object type ProfileImageDetails = object
url*: string url*: string
croppedImage*: string # TODO: Remove after https://github.com/status-im/status-go/issues/4977 croppedImage*: string
cropRectangle*: ImageCropRectangle cropRectangle*: ImageCropRectangle
type type
@ -189,7 +189,9 @@ proc init*(self: Controller) =
proc shouldStartWithOnboardingScreen*(self: Controller): bool = proc shouldStartWithOnboardingScreen*(self: Controller): bool =
return self.accountsService.openedAccounts().len == 0 return self.accountsService.openedAccounts().len == 0
# This is used when fetching backup failed and we create a new displayName and profileImage. # This is used in 2 flows, in case fetching backup failed and we create a new displayName and profileImage:
# 1. FirstRunOldUserImportSeedPhrase
# 2. FirstRunOldUserKeycardImport
# At this point the account is already created in the database. All that's left is to set the displayName and profileImage. # At this point the account is already created in the database. All that's left is to set the displayName and profileImage.
proc storeProfileDataAndProceedWithAppLoading*(self: Controller) = proc storeProfileDataAndProceedWithAppLoading*(self: Controller) =
self.delegate.removeAllKeycardUidPairsForCheckingForAChangeAfterLogin() # reason for this is in the table in AppController.nim file self.delegate.removeAllKeycardUidPairsForCheckingForAChangeAfterLogin() # reason for this is in the table in AppController.nim file
@ -201,12 +203,6 @@ proc storeProfileDataAndProceedWithAppLoading*(self: Controller) =
proc checkFetchingStatusAndProceed*(self: Controller) = proc checkFetchingStatusAndProceed*(self: Controller) =
self.delegate.checkFetchingStatusAndProceed() self.delegate.checkFetchingStatusAndProceed()
proc getGeneratedAccounts*(self: Controller): seq[GeneratedAccountDto] =
return self.accountsService.generatedAccounts()
proc getImportedAccount*(self: Controller): GeneratedAccountDto =
return self.accountsService.getImportedAccount()
proc getPasswordStrengthScore*(self: Controller, password, userName: string): int = proc getPasswordStrengthScore*(self: Controller, password, userName: string): int =
return self.generalService.getPasswordStrengthScore(password, userName) return self.generalService.getPasswordStrengthScore(password, userName)
@ -348,7 +344,6 @@ proc tryToObtainDataFromKeychain*(self: Controller) =
let selectedAccount = self.getSelectedLoginAccount() let selectedAccount = self.getSelectedLoginAccount()
self.keychainService.tryToObtainData(selectedAccount.keyUid) self.keychainService.tryToObtainData(selectedAccount.keyUid)
# TODO: Remove when implemented https://github.com/status-im/status-go/issues/4977
proc storeIdentityImage*(self: Controller): seq[Image] = proc storeIdentityImage*(self: Controller): seq[Image] =
if self.tmpProfileImageDetails.url.len == 0: if self.tmpProfileImageDetails.url.len == 0:
return return
@ -375,6 +370,7 @@ proc validMnemonic*(self: Controller, mnemonic: string): bool =
# validateMnemonicForImport checks if mnemonic is valid and not yet saved in local database # validateMnemonicForImport checks if mnemonic is valid and not yet saved in local database
proc validateMnemonicForImport*(self: Controller, mnemonic: string): bool = proc validateMnemonicForImport*(self: Controller, mnemonic: string): bool =
let (keyUID, err) = self.accountsService.validateMnemonic(mnemonic) let (keyUID, err) = self.accountsService.validateMnemonic(mnemonic)
if err.len != 0: if err.len != 0:
self.delegate.emitStartupError(err, StartupErrorType.ImportAccError) self.delegate.emitStartupError(err, StartupErrorType.ImportAccError)
@ -387,16 +383,6 @@ proc validateMnemonicForImport*(self: Controller, mnemonic: string): bool =
self.setSeedPhrase(mnemonic) self.setSeedPhrase(mnemonic)
return true return true
# TODO: Remove after https://github.com/status-im/status-go/issues/4977
proc importMnemonic*(self: Controller): bool =
let error = self.accountsService.importMnemonic(self.tmpSeedPhrase)
if(error.len == 0):
self.delegate.importAccountSuccess()
return true
else:
self.delegate.emitStartupError(error, StartupErrorType.ImportAccError)
return false
proc setupKeychain(self: Controller, store: bool) = proc setupKeychain(self: Controller, store: bool) =
if store: if store:
singletonInstance.localAccountSettings.setStoreToKeychainValue(LS_VALUE_NOT_NOW) singletonInstance.localAccountSettings.setStoreToKeychainValue(LS_VALUE_NOT_NOW)
@ -425,6 +411,7 @@ proc importAccountAndLogin*(self: Controller, storeToKeychain: bool, recoverAcco
self.connectToFetchingFromWakuEvents() self.connectToFetchingFromWakuEvents()
else: else:
self.delegate.moveToLoadingAppState() self.delegate.moveToLoadingAppState()
let error = self.accountsService.importAccountAndLogin( let error = self.accountsService.importAccountAndLogin(
self.tmpSeedPhrase, self.tmpSeedPhrase,
self.tmpPassword, self.tmpPassword,
@ -433,56 +420,48 @@ proc importAccountAndLogin*(self: Controller, storeToKeychain: bool, recoverAcco
self.tmpProfileImageDetails.url, self.tmpProfileImageDetails.url,
self.tmpProfileImageDetails.cropRectangle, self.tmpProfileImageDetails.cropRectangle,
) )
self.processCreateAccountResult(error, storeToKeychain) self.processCreateAccountResult(error, storeToKeychain)
proc storeKeycardAccountAndLogin*(self: Controller, storeToKeychain: bool, newKeycard: bool) = # NOTE: Called during FirstRunNewUserNewKeycardKeys and FirstRunNewUserImportSeedPhraseIntoKeycard
if self.importMnemonic(): # WARNING: Reuse `importAccountAndLogin` with custom parameters
self.delegate.moveToLoadingAppState() proc storeKeycardAccountAndLogin*(self: Controller, storeToKeychain: bool, newKeycard: bool = true) =
if newKeycard: self.delegate.moveToLoadingAppState()
self.delegate.storeDefaultKeyPairForNewKeycardUser() self.storeMetadataForNewKeycardUser()
self.storeMetadataForNewKeycardUser() let (_, flowEvent) = self.keycardService.getLastReceivedKeycardData()
else: let error = self.accountsService.importAccountAndLogin(
self.syncKeycardBasedOnAppWalletStateAfterLogin() self.tmpSeedPhrase,
let (_, flowEvent) = self.keycardService.getLastReceivedKeycardData() # we need this to get the correct instanceUID password = "", # For keycard it will be substituted with`encryption.publicKey` in status-go
self.accountsService.setupAccountKeycard(flowEvent, self.tmpDisplayName, useImportedAcc = true) false,
self.setupKeychain(storeToKeychain) self.tmpDisplayName,
else: self.tmpProfileImageDetails.url,
error "an error ocurred while importing mnemonic" self.tmpProfileImageDetails.cropRectangle,
keycardInstanceUID = flowEvent.instanceUID,
)
self.processCreateAccountResult(error, storeToKeychain)
# NOTE: Called during FirstRunOldUserKeycardImport
proc setupKeycardAccount*(self: Controller, storeToKeychain: bool, recoverAccount: bool = false) = proc setupKeycardAccount*(self: Controller, storeToKeychain: bool, recoverAccount: bool = false) =
if self.tmpKeycardEvent.keyUid.len == 0 or if self.tmpKeycardEvent.keyUid.len == 0 or
self.accountsService.openedAccountsContainsKeyUid(self.tmpKeycardEvent.keyUid): self.accountsService.openedAccountsContainsKeyUid(self.tmpKeycardEvent.keyUid):
self.delegate.emitStartupError(ACCOUNT_ALREADY_EXISTS_ERROR, StartupErrorType.ImportAccError) self.delegate.emitStartupError(ACCOUNT_ALREADY_EXISTS_ERROR, StartupErrorType.ImportAccError)
return return
if recoverAccount: if recoverAccount:
self.delegate.prepareAndInitFetchingData() self.delegate.prepareAndInitFetchingData()
self.connectToFetchingFromWakuEvents() self.connectToFetchingFromWakuEvents()
if self.tmpSeedPhrase.len > 0:
# if `tmpSeedPhrase` is not empty means user has recovered keycard via seed phrase
let accFromSeedPhrase = self.accountsService.createAccountFromMnemonic(self.tmpSeedPhrase, includeEncryption = true,
includeWhisper = true, includeRoot = true, includeDefaultWallet = true, includeEip1581 = true)
self.tmpKeycardEvent.masterKey.privateKey = accFromSeedPhrase.privateKey
self.tmpKeycardEvent.masterKey.publicKey = accFromSeedPhrase.publicKey
self.tmpKeycardEvent.masterKey.address = accFromSeedPhrase.address
self.tmpKeycardEvent.whisperKey.privateKey = accFromSeedPhrase.derivedAccounts.whisper.privateKey
self.tmpKeycardEvent.whisperKey.publicKey = accFromSeedPhrase.derivedAccounts.whisper.publicKey
self.tmpKeycardEvent.whisperKey.address = accFromSeedPhrase.derivedAccounts.whisper.address
self.tmpKeycardEvent.walletKey.privateKey = accFromSeedPhrase.derivedAccounts.defaultWallet.privateKey
self.tmpKeycardEvent.walletKey.publicKey = accFromSeedPhrase.derivedAccounts.defaultWallet.publicKey
self.tmpKeycardEvent.walletKey.address = accFromSeedPhrase.derivedAccounts.defaultWallet.address
self.tmpKeycardEvent.walletRootKey.privateKey = accFromSeedPhrase.derivedAccounts.walletRoot.privateKey
self.tmpKeycardEvent.walletRootKey.publicKey = accFromSeedPhrase.derivedAccounts.walletRoot.publicKey
self.tmpKeycardEvent.walletRootKey.address = accFromSeedPhrase.derivedAccounts.walletRoot.address
self.tmpKeycardEvent.eip1581Key.privateKey = accFromSeedPhrase.derivedAccounts.eip1581.privateKey
self.tmpKeycardEvent.eip1581Key.publicKey = accFromSeedPhrase.derivedAccounts.eip1581.publicKey
self.tmpKeycardEvent.eip1581Key.address = accFromSeedPhrase.derivedAccounts.eip1581.address
self.tmpKeycardEvent.encryptionKey.privateKey = accFromSeedPhrase.derivedAccounts.encryption.privateKey
self.tmpKeycardEvent.encryptionKey.publicKey = accFromSeedPhrase.derivedAccounts.encryption.publicKey
self.tmpKeycardEvent.encryptionKey.address = accFromSeedPhrase.derivedAccounts.encryption.address
self.syncKeycardBasedOnAppWalletStateAfterLogin() self.syncKeycardBasedOnAppWalletStateAfterLogin()
self.accountsService.setupAccountKeycard(self.tmpKeycardEvent, self.tmpDisplayName, useImportedAcc = false, recoverAccount)
self.setupKeychain(storeToKeychain) let error = self.accountsService.restoreKeycardAccountAndLogin(
self.tmpKeycardEvent,
recoverAccount,
self.tmpDisplayName,
self.tmpProfileImageDetails.url,
self.tmpProfileImageDetails.cropRectangle,
)
self.processCreateAccountResult(error, storeToKeychain)
proc getOpenedAccounts*(self: Controller): seq[AccountDto] = proc getOpenedAccounts*(self: Controller): seq[AccountDto] =
return self.accountsService.openedAccounts() return self.accountsService.openedAccounts()
@ -509,51 +488,41 @@ proc isSelectedAccountAKeycardAccount*(self: Controller): bool =
let selectedAccount = self.getSelectedLoginAccount() let selectedAccount = self.getSelectedLoginAccount()
return selectedAccount.keycardPairing.len > 0 return selectedAccount.keycardPairing.len > 0
proc login*(self: Controller) = proc login*(self: Controller, keycard: bool = false, keycardReplacement: bool = false) =
self.delegate.moveToLoadingAppState() self.delegate.moveToLoadingAppState()
let selectedAccount = self.getSelectedLoginAccount()
self.accountsService.login(selectedAccount, hashPassword(self.tmpPassword)) var passwordHash, chatPrivateKey, mnemonic = ""
if not keycard:
passwordHash = hashPassword(self.tmpPassword)
else:
passwordHash = self.tmpKeycardEvent.encryptionKey.publicKey
chatPrivateKey = self.tmpKeycardEvent.whisperKey.privateKey
mnemonic = self.tmpSeedPhrase
if keycard and keycardReplacement:
self.delegate.applyKeycardReplacementAfterLogin()
self.accountsService.login(
self.getSelectedLoginAccount(),
passwordHash,
chatPrivateKey,
mnemonic,
)
proc loginLocalPairingAccount*(self: Controller) = proc loginLocalPairingAccount*(self: Controller) =
self.delegate.moveToLoadingAppState() self.delegate.moveToLoadingAppState()
if self.localPairingStatus.chatKey.len == 0: self.accountsService.login(
self.accountsService.login(self.localPairingStatus.account, self.localPairingStatus.password) self.localPairingStatus.account,
else: self.localPairingStatus.password,
var kcEvent = KeycardEvent() chatPrivateKey = self.localPairingStatus.chatKey
kcEvent.keyUid = self.localPairingStatus.account.keyUid
kcEvent.whisperKey.privateKey = self.localPairingStatus.chatKey
kcEvent.encryptionKey.publicKey = self.localPairingStatus.password
discard self.accountsService.loginAccountKeycard(self.localPairingStatus.account, kcEvent)
proc loginAccountKeycard*(self: Controller, storeToKeychainValue: string, keycardReplacement = false) =
if keycardReplacement:
self.delegate.applyKeycardReplacementAfterLogin()
singletonInstance.localAccountSettings.setStoreToKeychainValue(storeToKeychainValue)
self.delegate.moveToLoadingAppState()
let selAcc = self.getSelectedLoginAccount()
let error = self.accountsService.loginAccountKeycard(selAcc, self.tmpKeycardEvent)
if(error.len > 0):
self.delegate.emitAccountLoginError(error)
proc loginAccountKeycardUsingSeedPhrase*(self: Controller, storeToKeychain: bool) =
let acc = self.accountsService.createAccountFromMnemonic(self.getSeedPhrase(), includeEncryption = true, includeWhisper = true)
let selAcc = self.getSelectedLoginAccount()
var kcData = KeycardEvent(
keyUid: acc.keyUid,
masterKey: KeyDetails(address: acc.address),
whisperKey: KeyDetails(privateKey: acc.derivedAccounts.whisper.privateKey),
encryptionKey: KeyDetails(publicKey: acc.derivedAccounts.encryption.publicKey)
) )
if acc.derivedAccounts.whisper.privateKey.startsWith("0x"):
kcData.whisperKey.privateKey = acc.derivedAccounts.whisper.privateKey[2..^1]
self.setupKeychain(storeToKeychain) # FIXME: Why do we even have storeToKeychain during login? Makes no sense
# https://github.com/status-im/status-desktop/issues/15167
self.delegate.moveToLoadingAppState() proc loginAccountKeycard*(self: Controller, storeToKeychain: bool, keycardReplacement = false) =
let error = self.accountsService.loginAccountKeycard(selAcc, kcData) # singletonInstance.localAccountSettings.setStoreToKeychainValue(storeToKeychainValue)
if(error.len > 0): self.login(keycard = true, keycardReplacement = keycardReplacement)
self.delegate.emitAccountLoginError(error)
proc convertKeycardProfileKeypairToRegular*(self: Controller) = proc convertKeycardProfileKeypairToRegular*(self: Controller) =
let acc = self.accountsService.createAccountFromMnemonic(self.getSeedPhrase(), includeEncryption = true) let acc = self.accountsService.createAccountFromMnemonic(self.getSeedPhrase(), includeEncryption = true)
@ -633,8 +602,8 @@ proc buildSeedPhrasesFromIndexes*(self: Controller, seedPhraseIndexes: seq[int])
proc generateRandomPUK*(self: Controller): string = proc generateRandomPUK*(self: Controller): string =
return self.keycardService.generateRandomPUK() return self.keycardService.generateRandomPUK()
# Stores metadata, default Status account only, to the keycard for a newly created keycard user.
proc storeMetadataForNewKeycardUser(self: Controller) = proc storeMetadataForNewKeycardUser(self: Controller) =
## Stores metadata, default Status account only, to the keycard for a newly created keycard user.
let paths = @[account_constants.PATH_DEFAULT_WALLET] let paths = @[account_constants.PATH_DEFAULT_WALLET]
self.runStoreMetadataFlow(self.getDisplayName(), self.getPin(), paths) self.runStoreMetadataFlow(self.getDisplayName(), self.getPin(), paths)

View File

@ -29,16 +29,16 @@ proc command(self: BiometricsState, controller: Controller, storeToKeychain: boo
## but since current implementation is like that and this is not a bug fixing issue, left as it is. ## but since current implementation is like that and this is not a bug fixing issue, left as it is.
controller.importAccountAndLogin(storeToKeychain, recoverAccount = true) controller.importAccountAndLogin(storeToKeychain, recoverAccount = true)
elif self.flowType == FlowType.FirstRunNewUserNewKeycardKeys: elif self.flowType == FlowType.FirstRunNewUserNewKeycardKeys:
controller.storeKeycardAccountAndLogin(storeToKeychain, newKeycard = true) controller.storeKeycardAccountAndLogin(storeToKeychain)
elif self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard: elif self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
controller.storeKeycardAccountAndLogin(storeToKeychain, newKeycard = true) controller.storeKeycardAccountAndLogin(storeToKeychain)
elif self.flowType == FlowType.FirstRunOldUserKeycardImport: elif self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.setupKeycardAccount(storeToKeychain, recoverAccount = true) controller.setupKeycardAccount(storeToKeychain, recoverAccount = true)
elif self.flowType == FlowType.LostKeycardReplacement: elif self.flowType == FlowType.LostKeycardReplacement:
self.storeToKeychain = storeToKeychain self.storeToKeychain = storeToKeychain
controller.startLoginFlowAutomatically(controller.getPin()) controller.startLoginFlowAutomatically(controller.getPin())
elif self.flowType == FlowType.LostKeycardConvertToRegularAccount: elif self.flowType == FlowType.LostKeycardConvertToRegularAccount:
controller.loginAccountKeycardUsingSeedPhrase(storeToKeychain) controller.loginAccountKeycard(storeToKeychain, keycardReplacement = false)
method executePrimaryCommand*(self: BiometricsState, controller: Controller) = method executePrimaryCommand*(self: BiometricsState, controller: Controller) =
self.command(controller, true) self.command(controller, true)
@ -49,10 +49,6 @@ method executeSecondaryCommand*(self: BiometricsState, controller: Controller) =
method resolveKeycardNextState*(self: BiometricsState, keycardFlowType: string, keycardEvent: KeycardEvent, method resolveKeycardNextState*(self: BiometricsState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State = controller: Controller): State =
if self.flowType == FlowType.LostKeycardReplacement: if self.flowType == FlowType.LostKeycardReplacement:
if keycardFlowType == ResponseTypeValueKeycardFlowResult and if keycardFlowType == ResponseTypeValueKeycardFlowResult and keycardEvent.error.len == 0:
keycardEvent.error.len == 0:
controller.setKeycardEvent(keycardEvent) controller.setKeycardEvent(keycardEvent)
var storeToKeychainValue = LS_VALUE_NEVER controller.loginAccountKeycard(self.storeToKeychain, keycardReplacement = true)
if self.storeToKeychain:
storeToKeychainValue = LS_VALUE_NOT_NOW
controller.loginAccountKeycard(storeToKeychainValue, keycardReplacement = true)

View File

@ -32,31 +32,34 @@ method resolveKeycardNextState*(self: KeycardEnterPinState, keycardFlowType: str
let state = ensureReaderAndCardPresenceOnboarding(self, keycardFlowType, keycardEvent, controller) let state = ensureReaderAndCardPresenceOnboarding(self, keycardFlowType, keycardEvent, controller)
if not state.isNil: if not state.isNil:
return state return state
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
if keycardFlowType == ResponseTypeValueEnterPIN and if self.flowType != FlowType.FirstRunOldUserKeycardImport:
keycardEvent.error.len > 0 and return
keycardEvent.error == RequestParamPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries) if keycardFlowType == ResponseTypeValueEnterPIN and
if keycardEvent.pinRetries > 0: keycardEvent.error.len > 0 and
return createState(StateType.KeycardWrongPin, self.flowType, self.getBackState) keycardEvent.error == RequestParamPIN:
controller.setRemainingAttempts(keycardEvent.pinRetries)
if keycardEvent.pinRetries > 0:
return createState(StateType.KeycardWrongPin, self.flowType, self.getBackState)
return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState) return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueEnterPUK and if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error.len == 0: keycardEvent.error.len > 0 and
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0: keycardEvent.error == RequestParamPUKRetries:
return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState) controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = true))
if keycardFlowType == ResponseTypeValueSwapCard and return createState(StateType.KeycardMaxPukRetriesReached, self.flowType, self.getBackState)
keycardEvent.error.len > 0 and if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error == RequestParamPUKRetries: keycardEvent.error.len > 0 and
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = true)) keycardEvent.error == RequestParamFreeSlots:
return createState(StateType.KeycardMaxPukRetriesReached, self.flowType, self.getBackState) return createState(StateType.KeycardMaxPairingSlotsReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueSwapCard and if keycardFlowType == ResponseTypeValueKeycardFlowResult:
keycardEvent.error.len > 0 and controller.setKeycardEvent(keycardEvent)
keycardEvent.error == RequestParamFreeSlots: if main_constants.SUPPORTS_FINGERPRINT:
return createState(StateType.KeycardMaxPairingSlotsReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setKeycardEvent(keycardEvent)
if not main_constants.IS_MACOS:
controller.setupKeycardAccount(storeToKeychain = false, recoverAccount = true)
return createState(StateType.ProfileFetching, self.flowType, nil)
let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser) let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser)
return createState(StateType.Biometrics, self.flowType, backState) return createState(StateType.Biometrics, self.flowType, backState)
controller.setupKeycardAccount(storeToKeychain = false, recoverAccount = true)
return createState(StateType.ProfileFetching, self.flowType, nil)

View File

@ -36,11 +36,11 @@ method resolveKeycardNextState*(self: KeycardEnterPukState, keycardFlowType: str
if keycardFlowType == ResponseTypeValueKeycardFlowResult: if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setKeycardEvent(keycardEvent) controller.setKeycardEvent(keycardEvent)
controller.setPukValid(true) controller.setPukValid(true)
if not main_constants.IS_MACOS: if main_constants.SUPPORTS_FINGERPRINT:
controller.setupKeycardAccount(storeToKeychain = false) let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser)
return nil return createState(StateType.Biometrics, self.flowType, backState)
let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser) controller.setupKeycardAccount(storeToKeychain = false)
return createState(StateType.Biometrics, self.flowType, backState) return nil
if self.flowType == FlowType.AppLogin: if self.flowType == FlowType.AppLogin:
if keycardFlowType == ResponseTypeValueEnterNewPIN and if keycardFlowType == ResponseTypeValueEnterNewPIN and
keycardEvent.error.len > 0 and keycardEvent.error.len > 0 and
@ -57,5 +57,7 @@ method resolveKeycardNextState*(self: KeycardEnterPukState, keycardFlowType: str
controller.setKeycardEvent(keycardEvent) controller.setKeycardEvent(keycardEvent)
controller.setPukValid(true) controller.setPukValid(true)
let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue() let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue()
controller.loginAccountKeycard(storeToKeychainValue) # FIXME: Make sure storeToKeychain is correct here. The idea is not to pass it at all
return nil # https://github.com/status-im/status-desktop/issues/15167
controller.loginAccountKeycard(storeToKeychain = false)
return nil

View File

@ -19,9 +19,9 @@ method getNextPrimaryState*(self: KeycardPinSetState, controller: Controller): S
return createState(StateType.UserProfileCreate, self.flowType, self.getBackState) return createState(StateType.UserProfileCreate, self.flowType, self.getBackState)
if self.flowType == FlowType.FirstRunOldUserKeycardImport: if self.flowType == FlowType.FirstRunOldUserKeycardImport:
if controller.getValidPuk(): if controller.getValidPuk():
if not main_constants.IS_MACOS: if main_constants.SUPPORTS_FINGERPRINT:
return createState(StateType.ProfileFetching, self.flowType, nil) return createState(StateType.Biometrics, self.flowType, self.getBackState)
return createState(StateType.Biometrics, self.flowType, self.getBackState) return createState(StateType.ProfileFetching, self.flowType, nil)
return createState(StateType.KeycardWrongPuk, self.flowType, self.getBackState) return createState(StateType.KeycardWrongPuk, self.flowType, self.getBackState)
if self.flowType == FlowType.AppLogin: if self.flowType == FlowType.AppLogin:
if controller.getRecoverKeycardUsingSeedPhraseWhileLoggingIn(): if controller.getRecoverKeycardUsingSeedPhraseWhileLoggingIn():
@ -35,7 +35,7 @@ method getNextPrimaryState*(self: KeycardPinSetState, controller: Controller): S
method executePrimaryCommand*(self: KeycardPinSetState, controller: Controller) = method executePrimaryCommand*(self: KeycardPinSetState, controller: Controller) =
if self.flowType == FlowType.FirstRunOldUserKeycardImport: if self.flowType == FlowType.FirstRunOldUserKeycardImport:
if main_constants.IS_MACOS: if main_constants.SUPPORTS_FINGERPRINT:
return return
if controller.getValidPuk(): if controller.getValidPuk():
controller.setupKeycardAccount(storeToKeychain = false, recoverAccount = true) controller.setupKeycardAccount(storeToKeychain = false, recoverAccount = true)
@ -44,24 +44,28 @@ method executePrimaryCommand*(self: KeycardPinSetState, controller: Controller)
controller.startLoginFlowAutomatically(controller.getPin()) controller.startLoginFlowAutomatically(controller.getPin())
return return
if controller.getValidPuk(): if controller.getValidPuk():
let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue() # FIXME: Make sure storeToKeychain is correct here. The idea is not to pass it at all
controller.loginAccountKeycard(storeToKeychainValue) # https://github.com/status-im/status-desktop/issues/15167
# let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue()
controller.loginAccountKeycard(storeToKeychain = false)
if self.flowType == FlowType.LostKeycardReplacement: if self.flowType == FlowType.LostKeycardReplacement:
controller.startLoginFlowAutomatically(controller.getPin()) controller.startLoginFlowAutomatically(controller.getPin())
method resolveKeycardNextState*(self: KeycardPinSetState, keycardFlowType: string, keycardEvent: KeycardEvent, method resolveKeycardNextState*(self: KeycardPinSetState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State = controller: Controller): State =
var storeToKeychainValue = LS_VALUE_NEVER
if self.flowType == FlowType.LostKeycardReplacement: if keycardFlowType != ResponseTypeValueKeycardFlowResult:
if keycardFlowType == ResponseTypeValueKeycardFlowResult and return
keycardEvent.error.len == 0:
if main_constants.IS_MACOS: if keycardEvent.error.len != 0:
storeToKeychainValue = LS_VALUE_NOT_NOW return
controller.setKeycardEvent(keycardEvent)
controller.loginAccountKeycard(storeToKeychainValue, keycardReplacement = true) let keycardReplacement = self.flowType == FlowType.LostKeycardReplacement
if self.flowType == FlowType.AppLogin: if not keycardReplacement and self.flowType != FlowType.AppLogin:
if keycardFlowType == ResponseTypeValueKeycardFlowResult and return
keycardEvent.error.len == 0:
# we are here in case of recover account from the login flow using seed phrase let storeToKeychain = keycardReplacement and main_constants.SUPPORTS_FINGERPRINT
controller.setKeycardEvent(keycardEvent)
controller.loginAccountKeycard(storeToKeychainValue, keycardReplacement = false) controller.setKeycardEvent(keycardEvent)
controller.loginAccountKeycard(storeToKeychain, keycardReplacement)

View File

@ -23,32 +23,34 @@ method resolveKeycardNextState*(self: KeycardWrongPinState, keycardFlowType: str
let state = ensureReaderAndCardPresenceOnboarding(self, keycardFlowType, keycardEvent, controller) let state = ensureReaderAndCardPresenceOnboarding(self, keycardFlowType, keycardEvent, controller)
if not state.isNil: if not state.isNil:
return state return state
if self.flowType == FlowType.FirstRunOldUserKeycardImport: if self.flowType != FlowType.FirstRunOldUserKeycardImport:
if keycardFlowType == ResponseTypeValueEnterPIN and return
keycardEvent.error.len > 0 and
keycardEvent.error == RequestParamPIN: if keycardFlowType == ResponseTypeValueEnterPIN and
controller.setRemainingAttempts(keycardEvent.pinRetries) keycardEvent.error.len > 0 and
if keycardEvent.pinRetries > 0: keycardEvent.error == RequestParamPIN:
return self controller.setRemainingAttempts(keycardEvent.pinRetries)
if keycardEvent.pinRetries > 0:
return self
return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState) return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueEnterPUK and return nil
keycardEvent.error.len == 0: if keycardFlowType == ResponseTypeValueSwapCard and
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0: keycardEvent.error.len > 0 and
return createState(StateType.KeycardMaxPinRetriesReached, self.flowType, self.getBackState) keycardEvent.error == RequestParamPUKRetries:
return nil controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = true))
if keycardFlowType == ResponseTypeValueSwapCard and return createState(StateType.KeycardMaxPukRetriesReached, self.flowType, self.getBackState)
keycardEvent.error.len > 0 and if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error == RequestParamPUKRetries: keycardEvent.error.len > 0 and
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = true)) keycardEvent.error == RequestParamFreeSlots:
return createState(StateType.KeycardMaxPukRetriesReached, self.flowType, self.getBackState) return createState(StateType.KeycardMaxPairingSlotsReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueSwapCard and if keycardFlowType == ResponseTypeValueKeycardFlowResult:
keycardEvent.error.len > 0 and controller.setKeycardEvent(keycardEvent)
keycardEvent.error == RequestParamFreeSlots: if main_constants.SUPPORTS_FINGERPRINT:
return createState(StateType.KeycardMaxPairingSlotsReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setKeycardEvent(keycardEvent)
if not main_constants.IS_MACOS:
controller.setupKeycardAccount(storeToKeychain = false)
return nil
let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser) let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser)
return createState(StateType.Biometrics, self.flowType, backState) return createState(StateType.Biometrics, self.flowType, backState)
controller.setupKeycardAccount(storeToKeychain = false)
return nil

View File

@ -38,11 +38,11 @@ method resolveKeycardNextState*(self: KeycardWrongPukState, keycardFlowType: str
if keycardFlowType == ResponseTypeValueKeycardFlowResult: if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setKeycardEvent(keycardEvent) controller.setKeycardEvent(keycardEvent)
controller.setPukValid(true) controller.setPukValid(true)
if not main_constants.IS_MACOS: if main_constants.SUPPORTS_FINGERPRINT:
controller.setupKeycardAccount(storeToKeychain = false, recoverAccount = true) let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser)
return createState(StateType.ProfileFetching, self.flowType, nil) return createState(StateType.Biometrics, self.flowType, backState)
let backState = findBackStateWithTargetedStateType(self, StateType.RecoverOldUser) controller.setupKeycardAccount(storeToKeychain = false, recoverAccount = true)
return createState(StateType.Biometrics, self.flowType, backState) return createState(StateType.ProfileFetching, self.flowType, nil)
if self.flowType == FlowType.AppLogin: if self.flowType == FlowType.AppLogin:
if keycardFlowType == ResponseTypeValueEnterPUK and if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len > 0 and keycardEvent.error.len > 0 and
@ -60,5 +60,7 @@ method resolveKeycardNextState*(self: KeycardWrongPukState, keycardFlowType: str
controller.setKeycardEvent(keycardEvent) controller.setKeycardEvent(keycardEvent)
controller.setPukValid(true) controller.setPukValid(true)
let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue() let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue()
controller.loginAccountKeycard(storeToKeychainValue) # FIXME: Make sure storeToKeychain is correct here. The idea is not to pass it at all
return nil # https://github.com/status-im/status-desktop/issues/15167
controller.loginAccountKeycard(false)
return nil

View File

@ -11,4 +11,6 @@ proc delete*(self: LoginKeycardPinVerifiedState) =
method executePrimaryCommand*(self: LoginKeycardPinVerifiedState, controller: Controller) = method executePrimaryCommand*(self: LoginKeycardPinVerifiedState, controller: Controller) =
if self.flowType == FlowType.AppLogin: if self.flowType == FlowType.AppLogin:
let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue() let storeToKeychainValue = singletonInstance.localAccountSettings.getStoreToKeychainValue()
controller.loginAccountKeycard(storeToKeychainValue) # FIXME: Make sure storeToKeychain is correct here. The idea is not to pass it at all
# https://github.com/status-im/status-desktop/issues/15167
controller.loginAccountKeycard(false)

View File

@ -25,8 +25,8 @@ method executePrimaryCommand*(self: UserProfileConfirmPasswordState, controller:
elif self.flowType == FlowType.FirstRunNewUserImportSeedPhrase: elif self.flowType == FlowType.FirstRunNewUserImportSeedPhrase:
controller.importAccountAndLogin(storeToKeychain) controller.importAccountAndLogin(storeToKeychain)
elif self.flowType == FlowType.FirstRunNewUserNewKeycardKeys: elif self.flowType == FlowType.FirstRunNewUserNewKeycardKeys:
controller.storeKeycardAccountAndLogin(storeToKeychain, newKeycard = true) controller.storeKeycardAccountAndLogin(storeToKeychain)
elif self.flowType == FlowType.FirstRunOldUserImportSeedPhrase: elif self.flowType == FlowType.FirstRunOldUserImportSeedPhrase:
controller.importAccountAndLogin(storeToKeychain, recoverAccount = true) controller.importAccountAndLogin(storeToKeychain, recoverAccount = true)
elif self.flowType == FlowType.LostKeycardConvertToRegularAccount: elif self.flowType == FlowType.LostKeycardConvertToRegularAccount:
controller.loginAccountKeycardUsingSeedPhrase(storeToKeychain) controller.loginAccountKeycard(storeToKeychain, keycardReplacement = true)

View File

@ -68,9 +68,6 @@ method startUpUIRaised*(self: AccessInterface) {.base.} =
method emitLogOut*(self: AccessInterface) {.base.} = method emitLogOut*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method getImportedAccount*(self: AccessInterface): GeneratedAccountDto {.base.} =
raise newException(ValueError, "No implementation available")
method generateImage*(self: AccessInterface, imageUrl: string, aX: int, aY: int, bX: int, bY: int): string {.base.} = method generateImage*(self: AccessInterface, imageUrl: string, aX: int, aY: int, bX: int, bY: int): string {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
@ -110,9 +107,6 @@ method emitStartupError*(self: AccessInterface, error: string, errType: StartupE
method validMnemonic*(self: AccessInterface, mnemonic: string): bool {.base.} = method validMnemonic*(self: AccessInterface, mnemonic: string): bool {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method importAccountSuccess*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method setSelectedLoginAccount*(self: AccessInterface, item: login_acc_item.Item) {.base.} = method setSelectedLoginAccount*(self: AccessInterface, item: login_acc_item.Item) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
@ -152,9 +146,6 @@ method setRemainingAttempts*(self: AccessInterface, value: int) {.base.} =
method runFactoryResetPopup*(self: AccessInterface) {.base.} = method runFactoryResetPopup*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method storeDefaultKeyPairForNewKeycardUser*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method syncKeycardBasedOnAppWalletStateAfterLogin*(self: AccessInterface) {.base.} = method syncKeycardBasedOnAppWalletStateAfterLogin*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
@ -238,7 +229,6 @@ type
c.userLoggedIn() c.userLoggedIn()
c.finishAppLoading() c.finishAppLoading()
c.appReady() c.appReady()
c.storeDefaultKeyPairForNewKeycardUser()
c.syncKeycardBasedOnAppWalletStateAfterLogin() c.syncKeycardBasedOnAppWalletStateAfterLogin()
c.applyKeycardReplacementAfterLogin() c.applyKeycardReplacementAfterLogin()
c.addToKeycardUidPairsToCheckForAChangeAfterLogin(string, string) c.addToKeycardUidPairsToCheckForAChangeAfterLogin(string, string)

View File

@ -1,29 +0,0 @@
type
Item* = object
id: string
alias: string
address: string
pubKey: string
keyUid: string
proc initItem*(id, alias, address, pubKey, keyUid: string): Item =
result.id = id
result.alias = alias
result.address = address
result.pubKey = pubKey
result.keyUid = keyUid
proc getId*(self: Item): string =
return self.id
proc getAlias*(self: Item): string =
return self.alias
proc getAddress*(self: Item): string =
return self.address
proc getPubKey*(self: Item): string =
return self.pubKey
proc getKeyUid*(self: Item): string =
return self.keyUid

View File

@ -1,66 +0,0 @@
import NimQml, Tables, strutils
import generated_account_item
type
ModelRole {.pure.} = enum
Id = UserRole + 1
Alias
Address
PubKey
KeyUid
QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: Model) =
self.QAbstractListModel.setup
proc newModel*(): Model =
new(result, delete)
result.setup
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.Id.int:"accountId",
ModelRole.Alias.int:"username",
ModelRole.Address.int:"address",
ModelRole.PubKey.int:"pubKey",
ModelRole.KeyUid.int:"keyUid"
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.Id:
result = newQVariant(item.getId())
of ModelRole.Alias:
result = newQVariant(item.getAlias())
of ModelRole.Address:
result = newQVariant(item.getAddress())
of ModelRole.PubKey:
result = newQVariant(item.getPubKey())
of ModelRole.KeyUid:
result = newQVariant(item.getKeyUid())
proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel()
self.items = items
self.endResetModel()

View File

@ -3,7 +3,6 @@ import NimQml, chronicles
import io_interface import io_interface
import view, controller import view, controller
import internal/[state, state_factory] import internal/[state, state_factory]
import models/generated_account_item as gen_acc_item
import models/login_account_item as login_acc_item import models/login_account_item as login_acc_item
import models/fetching_data_model as fetch_model import models/fetching_data_model as fetch_model
import app/global/global_singleton import app/global/global_singleton
@ -119,12 +118,6 @@ method load*[T](self: Module[T]) =
singletonInstance.engine.setRootContextProperty("startupModule", self.viewVariant) singletonInstance.engine.setRootContextProperty("startupModule", self.viewVariant)
self.controller.init() self.controller.init()
let generatedAccounts = self.controller.getGeneratedAccounts()
var accounts: seq[gen_acc_item.Item]
for acc in generatedAccounts:
accounts.add(gen_acc_item.initItem(acc.id, acc.alias, acc.address, acc.derivedAccounts.whisper.publicKey, acc.keyUid))
self.view.setGeneratedAccountList(accounts)
if self.controller.shouldStartWithOnboardingScreen(): if self.controller.shouldStartWithOnboardingScreen():
self.view.setCurrentStartupState(newWelcomeState(state.FlowType.General, nil)) self.view.setCurrentStartupState(newWelcomeState(state.FlowType.General, nil))
else: else:
@ -262,9 +255,6 @@ method onQuinaryActionClicked*[T](self: Module[T]) =
self.view.setCurrentStartupState(nextState) self.view.setCurrentStartupState(nextState)
debug "quinary_action - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType() debug "quinary_action - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
method getImportedAccount*[T](self: Module[T]): GeneratedAccountDto =
return self.controller.getImportedAccount()
method generateImage*[T](self: Module[T], imageUrl: string, aX: int, aY: int, bX: int, bY: int): string = method generateImage*[T](self: Module[T], imageUrl: string, aX: int, aY: int, bX: int, bY: int): string =
return self.controller.generateImage(imageUrl, aX, aY, bX, bY) return self.controller.generateImage(imageUrl, aX, aY, bX, bY)
@ -304,9 +294,6 @@ method emitStartupError*[T](self: Module[T], error: string, errType: StartupErro
method validMnemonic*[T](self: Module[T], mnemonic: string): bool = method validMnemonic*[T](self: Module[T], mnemonic: string): bool =
return self.controller.validMnemonic(mnemonic) return self.controller.validMnemonic(mnemonic)
method importAccountSuccess*[T](self: Module[T]) =
self.view.importAccountSuccess()
method setSelectedLoginAccount*[T](self: Module[T], item: login_acc_item.Item) = method setSelectedLoginAccount*[T](self: Module[T], item: login_acc_item.Item) =
self.controller.cancelCurrentFlow() self.controller.cancelCurrentFlow()
if item.getKeyUid().len == 0: if item.getKeyUid().len == 0:
@ -535,9 +522,6 @@ method onSharedKeycarModuleFlowTerminated*[T](self: Module[T], lastStepInTheCurr
self.view.setCurrentStartupState(newState) self.view.setCurrentStartupState(newState)
debug "new state for onboarding/login flow continuation after shared flow is terminated", setCurrFlow=newState.flowType(), newCurrState=newState.stateType() debug "new state for onboarding/login flow continuation after shared flow is terminated", setCurrFlow=newState.flowType(), newCurrState=newState.stateType()
method storeDefaultKeyPairForNewKeycardUser*[T](self: Module[T]) =
self.delegate.storeDefaultKeyPairForNewKeycardUser()
method syncKeycardBasedOnAppWalletStateAfterLogin*[T](self: Module[T]) = method syncKeycardBasedOnAppWalletStateAfterLogin*[T](self: Module[T]) =
self.delegate.syncKeycardBasedOnAppWalletStateAfterLogin() self.delegate.syncKeycardBasedOnAppWalletStateAfterLogin()

View File

@ -2,8 +2,6 @@ import NimQml, chronicles
import io_interface import io_interface
import selected_login_account import selected_login_account
import internal/[state, state_wrapper] import internal/[state, state_wrapper]
import models/generated_account_model as gen_acc_model
import models/generated_account_item as gen_acc_item
import models/login_account_model as login_acc_model import models/login_account_model as login_acc_model
import models/login_account_item as login_acc_item import models/login_account_item as login_acc_item
import models/fetching_data_model as fetch_model import models/fetching_data_model as fetch_model
@ -25,8 +23,6 @@ QtObject:
showBeforeGetStartedPopup: bool showBeforeGetStartedPopup: bool
currentStartupState: StateWrapper currentStartupState: StateWrapper
currentStartupStateVariant: QVariant currentStartupStateVariant: QVariant
generatedAccountsModel: gen_acc_model.Model
generatedAccountsModelVariant: QVariant
selectedLoginAccount: SelectedLoginAccount selectedLoginAccount: SelectedLoginAccount
selectedLoginAccountVariant: QVariant selectedLoginAccountVariant: QVariant
loginAccountsModel: login_acc_model.Model loginAccountsModel: login_acc_model.Model
@ -41,8 +37,6 @@ QtObject:
proc delete*(self: View) = proc delete*(self: View) =
self.currentStartupStateVariant.delete self.currentStartupStateVariant.delete
self.currentStartupState.delete self.currentStartupState.delete
self.generatedAccountsModel.delete
self.generatedAccountsModelVariant.delete
self.selectedLoginAccount.delete self.selectedLoginAccount.delete
self.selectedLoginAccountVariant.delete self.selectedLoginAccountVariant.delete
self.loginAccountsModel.delete self.loginAccountsModel.delete
@ -62,8 +56,6 @@ QtObject:
result.appState = AppState.StartupState result.appState = AppState.StartupState
result.currentStartupState = newStateWrapper() result.currentStartupState = newStateWrapper()
result.currentStartupStateVariant = newQVariant(result.currentStartupState) result.currentStartupStateVariant = newQVariant(result.currentStartupState)
result.generatedAccountsModel = gen_acc_model.newModel()
result.generatedAccountsModelVariant = newQVariant(result.generatedAccountsModel)
result.selectedLoginAccount = newSelectedLoginAccount() result.selectedLoginAccount = newSelectedLoginAccount()
result.selectedLoginAccountVariant = newQVariant(result.selectedLoginAccount) result.selectedLoginAccountVariant = newQVariant(result.selectedLoginAccount)
result.loginAccountsModel = login_acc_model.newModel() result.loginAccountsModel = login_acc_model.newModel()
@ -138,35 +130,6 @@ QtObject:
proc emitLogOut*(self: View) = proc emitLogOut*(self: View) =
self.logOut() self.logOut()
proc generatedAccountsModelChanged*(self: View) {.signal.}
proc getGeneratedAccountsModel(self: View): QVariant {.slot.} =
return self.generatedAccountsModelVariant
proc setGeneratedAccountList*(self: View, accounts: seq[gen_acc_item.Item]) =
self.generatedAccountsModel.setItems(accounts)
self.generatedAccountsModelChanged()
QtProperty[QVariant] generatedAccountsModel:
read = getGeneratedAccountsModel
notify = generatedAccountsModelChanged
proc importedAccountChanged*(self: View) {.signal.}
proc getImportedAccountAlias*(self: View): string {.slot.} =
return self.delegate.getImportedAccount().alias
QtProperty[string] importedAccountAlias:
read = getImportedAccountAlias
notify = importedAccountChanged
proc getImportedAccountAddress*(self: View): string {.slot.} =
return self.delegate.getImportedAccount().address
QtProperty[string] importedAccountAddress:
read = getImportedAccountAddress
notify = importedAccountChanged
proc getImportedAccountPubKey*(self: View): string {.slot.} =
return self.delegate.getImportedAccount().derivedAccounts.whisper.publicKey
QtProperty[string] importedAccountPubKey:
read = getImportedAccountPubKey
notify = importedAccountChanged
proc generateImage*(self: View, imageUrl: string, aX: int, aY: int, bX: int, bY: int): string {.slot.} = proc generateImage*(self: View, imageUrl: string, aX: int, aY: int, bX: int, bY: int): string {.slot.} =
return self.delegate.generateImage(imageUrl, aX, aY, bX, bY) return self.delegate.generateImage(imageUrl, aX, aY, bX, bY)
@ -207,9 +170,6 @@ QtObject:
proc validMnemonic*(self: View, mnemonic: string): bool {.slot.} = proc validMnemonic*(self: View, mnemonic: string): bool {.slot.} =
return self.delegate.validMnemonic(mnemonic) return self.delegate.validMnemonic(mnemonic)
proc importAccountSuccess*(self: View) =
self.importedAccountChanged()
proc selectedLoginAccountChanged*(self: View) {.signal.} proc selectedLoginAccountChanged*(self: View) {.signal.}
proc getSelectedLoginAccount(self: View): QVariant {.slot.} = proc getSelectedLoginAccount(self: View): QVariant {.slot.} =
return self.selectedLoginAccountVariant return self.selectedLoginAccountVariant

View File

@ -1,6 +1,6 @@
import json, random, times, strutils, sugar, os, re, chronicles import json, times, strutils, sugar, os, re, chronicles
import nimcrypto import nimcrypto
import signing_phrases, account_constants import account_constants
import ../../constants as main_constants import ../../constants as main_constants
@ -26,16 +26,6 @@ proc prefix*(methodName: string, isExt:bool = true): string =
result = result & (if isExt: "ext_" else: "_") result = result & (if isExt: "ext_" else: "_")
result = result & methodName result = result & methodName
proc generateSigningPhrase*(count: int): string =
let now = getTime()
var rng = initRand(now.toUnix * 1000000000 + now.nanosecond)
var phrases: seq[string] = @[]
for i in 1..count:
phrases.add(rng.sample(signing_phrases.phrases))
result = phrases.join(" ")
proc first*(jArray: JsonNode, fieldName, id: string): JsonNode = proc first*(jArray: JsonNode, fieldName, id: string): JsonNode =
if jArray == nil: if jArray == nil:
return nil return nil
@ -91,4 +81,4 @@ proc contractUniqueKey*(chainId: int, contractAddress: string): string =
proc intersectSeqs*[T](seq1, seq2: seq[T]): seq[T] = proc intersectSeqs*[T](seq1, seq2: seq[T]): seq[T] =
for item in seq1: for item in seq1:
if item in seq2: if item in seq2:
result.add(item) result.add(item)

View File

@ -7,7 +7,7 @@ export image_crop_rectangle
type type
CreateAccountRequest* = object CreateAccountRequest* = object
backupDisabledDataDir*: string rootDataDir*: string
kdfIterations*: int kdfIterations*: int
deviceName*: string deviceName*: string
displayName*: string displayName*: string
@ -38,9 +38,12 @@ type
torrentConfigEnabled*: Option[bool] torrentConfigEnabled*: Option[bool]
torrentConfigPort*: Option[int] torrentConfigPort*: Option[int]
keycardInstanceUID*: string
keycardPairingDataFile*: string
proc toJson*(self: CreateAccountRequest): JsonNode = proc toJson*(self: CreateAccountRequest): JsonNode =
result = %*{ result = %*{
"backupDisabledDataDir": self.backupDisabledDataDir, "rootDataDir": self.rootDataDir,
"kdfIterations": self.kdfIterations, "kdfIterations": self.kdfIterations,
"deviceName": self.deviceName, "deviceName": self.deviceName,
"displayName": self.displayName, "displayName": self.displayName,
@ -54,6 +57,8 @@ proc toJson*(self: CreateAccountRequest): JsonNode =
"logEnabled": self.logEnabled, "logEnabled": self.logEnabled,
"previewPrivacy": self.previewPrivacy, "previewPrivacy": self.previewPrivacy,
"upstreamConfig": self.upstreamConfig, "upstreamConfig": self.upstreamConfig,
"keycardInstanceUID": self.keycardInstanceUID,
"keycardPairingDataFile": self.keycardPairingDataFile,
} }
if self.logLevel.isSome(): if self.logLevel.isSome():

View File

@ -0,0 +1,28 @@
import json
type
KeycardData* = ref object
keyUID*: string
address*: string
whisperPrivateKey*: string
whisperPublicKey*: string
whisperAddress*: string
walletPublicKey*: string
walletAddress*: string
walletRootAddress*: string
eip1581Address*: string
encryptionPublicKey*: string
proc toJson*(self: KeycardData): JsonNode =
result = %*{
"keyUID": self.keyUID,
"address": self.address,
"whisperPrivateKey": self.whisperPrivateKey,
"whisperPublicKey": self.whisperPublicKey,
"whisperAddress": self.whisperAddress,
"walletPublicKey": self.walletPublicKey,
"walletAddress": self.walletAddress,
"walletRootAddress": self.walletRootAddress,
"eip1581Address": self.eip1581Address,
"encryptionPublicKey": self.encryptionPublicKey
}

View File

@ -1,5 +1,7 @@
import json import json
import ./wallet_secretes_config import wallet_secretes_config
export wallet_secretes_config
type type
LoginAccountRequest* = object LoginAccountRequest* = object
@ -9,6 +11,8 @@ type
runtimeLogLevel*: string runtimeLogLevel*: string
wakuV2Nameserver*: string wakuV2Nameserver*: string
bandwidthStatsEnabled*: bool bandwidthStatsEnabled*: bool
keycardWhisperPrivateKey*: string
mnemonic*: string
walletSecretsConfig*: WalletSecretsConfig walletSecretsConfig*: WalletSecretsConfig
proc toJson*(self: LoginAccountRequest): JsonNode = proc toJson*(self: LoginAccountRequest): JsonNode =
@ -19,6 +23,8 @@ proc toJson*(self: LoginAccountRequest): JsonNode =
"runtimeLogLevel": self.runtimeLogLevel, "runtimeLogLevel": self.runtimeLogLevel,
"wakuV2Nameserver": self.wakuV2Nameserver, "wakuV2Nameserver": self.wakuV2Nameserver,
"bandwidthStatsEnabled": self.bandwidthStatsEnabled, "bandwidthStatsEnabled": self.bandwidthStatsEnabled,
"keycardWhisperPrivateKey": self.keycardWhisperPrivateKey,
"mnemonic": self.mnemonic,
} }
for key, value in self.walletSecretsConfig.toJson().pairs(): for key, value in self.walletSecretsConfig.toJson().pairs():
result[key] = value result[key] = value

View File

@ -1,18 +1,25 @@
import json import json
import create_account_request import create_account_request, keycard_data
export create_account_request, keycard_data
type type
RestoreAccountRequest* = object RestoreAccountRequest* = object
mnemonic*: string mnemonic*: string
keycard*: KeycardData
fetchBackup*: bool fetchBackup*: bool
createAccountRequest*: CreateAccountRequest createAccountRequest*: CreateAccountRequest
proc toJson*(self: RestoreAccountRequest): JsonNode = proc toJson*(self: RestoreAccountRequest): JsonNode =
result = %*{ result = %*{
"mnemonic": self.mnemonic, "mnemonic": self.mnemonic,
"fetchBackup": self.fetchBackup "fetchBackup": self.fetchBackup,
} }
if self.keycard != nil:
result["keycard"] = self.keycard.toJson()
for key, value in self.createAccountRequest.toJson().pairs(): for key, value in self.createAccountRequest.toJson().pairs():
result[key] = value result[key] = value

View File

@ -1,11 +1,10 @@
import NimQml, Tables, os, json, stew/shims/strformat, sequtils, strutils, uuids, times, std/options import NimQml, Tables, os, json, stew/shims/strformat, sequtils, strutils, times, std/options
import json_serialization, chronicles import json_serialization, chronicles
import ../../../app/global/global_singleton import ../../../app/global/global_singleton
import ./dto/accounts as dto_accounts import ./dto/accounts as dto_accounts
import ./dto/generated_accounts as dto_generated_accounts import ./dto/generated_accounts as dto_generated_accounts
import ./dto/login_request import ./dto/login_request
import ./dto/create_account_request
import ./dto/restore_account_request import ./dto/restore_account_request
from ../keycard/service import KeycardEvent, KeyDetails from ../keycard/service import KeycardEvent, KeyDetails
@ -20,8 +19,6 @@ import ../../../app/core/fleets/fleet_configuration
import ../../common/[account_constants, network_constants, utils] import ../../common/[account_constants, network_constants, utils]
import ../../../constants as main_constants import ../../../constants as main_constants
import ../settings/dto/settings as settings
export dto_accounts export dto_accounts
export dto_generated_accounts export dto_generated_accounts
@ -29,8 +26,6 @@ export dto_generated_accounts
logScope: logScope:
topics = "accounts-service" topics = "accounts-service"
const DEFAULT_WALLET_ACCOUNT_NAME = "Account 1"
const PATHS = @[PATH_WALLET_ROOT, PATH_EIP_1581, PATH_WHISPER, PATH_DEFAULT_WALLET, PATH_ENCRYPTION]
const ACCOUNT_ALREADY_EXISTS_ERROR* = "account already exists" const ACCOUNT_ALREADY_EXISTS_ERROR* = "account already exists"
const KDF_ITERATIONS* {.intdefine.} = 256_000 const KDF_ITERATIONS* {.intdefine.} = 256_000
const DEFAULT_CUSTOMIZATION_COLOR = "primary" # to match `CustomizationColor` on the go side const DEFAULT_CUSTOMIZATION_COLOR = "primary" # to match `CustomizationColor` on the go side
@ -62,15 +57,15 @@ QtObject:
events: EventEmitter events: EventEmitter
threadpool: ThreadPool threadpool: ThreadPool
fleetConfiguration: FleetConfiguration fleetConfiguration: FleetConfiguration
generatedAccounts: seq[GeneratedAccountDto]
accounts: seq[AccountDto] accounts: seq[AccountDto]
loggedInAccount: AccountDto loggedInAccount: AccountDto
importedAccount: GeneratedAccountDto
keyStoreDir: string keyStoreDir: string
defaultWalletEmoji: string defaultWalletEmoji: string
tmpAccount: AccountDto tmpAccount: AccountDto
tmpHashedPassword: string tmpHashedPassword: string
proc restoreAccountAndLogin(self: Service, request: RestoreAccountRequest): string
proc delete*(self: Service) = proc delete*(self: Service) =
self.QObject.delete self.QObject.delete
@ -83,6 +78,8 @@ QtObject:
result.keyStoreDir = main_constants.ROOTKEYSTOREDIR result.keyStoreDir = main_constants.ROOTKEYSTOREDIR
result.defaultWalletEmoji = "" result.defaultWalletEmoji = ""
proc scheduleReencrpytion(self: Service, account: AccountDto, hashedPassword: string, timeout: int = 1000)
proc setLocalAccountSettingsFile(self: Service) = proc setLocalAccountSettingsFile(self: Service) =
if self.loggedInAccount.isValid(): if self.loggedInAccount.isValid():
singletonInstance.localAccountSettings.setFileName(self.loggedInAccount.name) singletonInstance.localAccountSettings.setFileName(self.loggedInAccount.name)
@ -99,9 +96,6 @@ QtObject:
self.loggedInAccount.images = images self.loggedInAccount.images = images
singletonInstance.localAccountSettings.setFileName(displayName) singletonInstance.localAccountSettings.setFileName(displayName)
proc getImportedAccount*(self: Service): GeneratedAccountDto =
return self.importedAccount
proc setKeyStoreDir(self: Service, key: string) = proc setKeyStoreDir(self: Service, key: string) =
self.keyStoreDir = joinPath(main_constants.ROOTKEYSTOREDIR, key) & main_constants.sep self.keyStoreDir = joinPath(main_constants.ROOTKEYSTOREDIR, key) & main_constants.sep
discard status_general.initKeystore(self.keyStoreDir) discard status_general.initKeystore(self.keyStoreDir)
@ -118,22 +112,10 @@ QtObject:
self.updateLoggedInAccount(receivedData.backedUpProfile.displayName, receivedData.backedUpProfile.images) self.updateLoggedInAccount(receivedData.backedUpProfile.displayName, receivedData.backedUpProfile.images)
proc init*(self: Service) = proc init*(self: Service) =
try: discard
let response = status_account.generateAddresses(PATHS)
self.generatedAccounts = map(response.result.getElems(),
proc(x: JsonNode): GeneratedAccountDto = toGeneratedAccountDto(x))
for account in self.generatedAccounts.mitems:
account.alias = generateAliasFromPk(account.derivedAccounts.whisper.publicKey)
except Exception as e:
error "error: ", procName="init", errName = e.name, errDesription = e.msg
proc clear*(self: Service) = proc clear*(self: Service) =
self.generatedAccounts = @[]
self.loggedInAccount = AccountDto() self.loggedInAccount = AccountDto()
self.importedAccount = GeneratedAccountDto()
proc validateMnemonic*(self: Service, mnemonic: string): (string, string) = proc validateMnemonic*(self: Service, mnemonic: string): (string, string) =
try: try:
@ -144,13 +126,6 @@ QtObject:
except Exception as e: except Exception as e:
error "error: ", procName="validateMnemonic", errName = e.name, errDesription = e.msg error "error: ", procName="validateMnemonic", errName = e.name, errDesription = e.msg
proc generatedAccounts*(self: Service): seq[GeneratedAccountDto] =
if(self.generatedAccounts.len == 0):
error "There was some issue initiating account service"
return
result = self.generatedAccounts
proc openedAccounts*(self: Service): seq[AccountDto] = proc openedAccounts*(self: Service): seq[AccountDto] =
try: try:
let response = status_account.openedAccounts(main_constants.STATUSGODIR) let response = status_account.openedAccounts(main_constants.STATUSGODIR)
@ -165,106 +140,12 @@ QtObject:
proc openedAccountsContainsKeyUid*(self: Service, keyUid: string): bool = proc openedAccountsContainsKeyUid*(self: Service, keyUid: string): bool =
return (keyUID in self.openedAccounts().mapIt(it.keyUid)) return (keyUID in self.openedAccounts().mapIt(it.keyUid))
proc saveKeycardAccountAndLogin(self: Service, chatKey, password: string, account, subaccounts, settings,
config: JsonNode): AccountDto =
try:
let response = status_account.saveAccountAndLoginWithKeycard(chatKey, password, account, subaccounts, settings, config)
var error = "response doesn't contain \"error\""
if(response.result.contains("error")):
error = response.result["error"].getStr
if error == "":
debug "Account saved succesfully"
result = toAccountDto(account)
return
let err = "Error saving account and logging in via keycard : " & error
error "error: ", procName="saveKeycardAccountAndLogin", errDesription = err
except Exception as e:
error "error: ", procName="saveKeycardAccountAndLogin", errName = e.name, errDesription = e.msg
proc prepareSubaccountJsonObject(self: Service, account: GeneratedAccountDto, displayName: string):
JsonNode =
result = %* [
{
"public-key": account.derivedAccounts.defaultWallet.publicKey,
"address": account.derivedAccounts.defaultWallet.address,
"colorId": DEFAULT_CUSTOMIZATION_COLOR,
"wallet": true,
"path": PATH_DEFAULT_WALLET,
"name": DEFAULT_WALLET_ACCOUNT_NAME,
"derived-from": account.address,
"emoji": self.defaultWalletEmoji
},
{
"public-key": account.derivedAccounts.whisper.publicKey,
"address": account.derivedAccounts.whisper.address,
"name": if displayName == "": account.alias else: displayName,
"path": PATH_WHISPER,
"chat": true,
"derived-from": ""
}
]
proc getSubaccountDataForAccountId(self: Service, accountId: string, displayName: string): JsonNode =
for acc in self.generatedAccounts:
if(acc.id == accountId):
return self.prepareSubaccountJsonObject(acc, displayName)
if(self.importedAccount.isValid()):
if(self.importedAccount.id == accountId):
return self.prepareSubaccountJsonObject(self.importedAccount, displayName)
proc toStatusGoSupportedLogLevel*(logLevel: string): string = proc toStatusGoSupportedLogLevel*(logLevel: string): string =
if logLevel == "TRACE": if logLevel == "TRACE":
return "DEBUG" return "DEBUG"
return logLevel return logLevel
proc prepareAccountSettingsJsonObject(self: Service, account: GeneratedAccountDto, # TODO: Remove after https://github.com/status-im/status-desktop/issues/11435
installationId: string, displayName: string, withoutMnemonic: bool): JsonNode =
result = %* {
"key-uid": account.keyUid,
"mnemonic": if withoutMnemonic: "" else: account.mnemonic,
"public-key": account.derivedAccounts.whisper.publicKey,
"name": account.alias,
"display-name": displayName,
"address": account.address,
"eip1581-address": account.derivedAccounts.eip1581.address,
"dapps-address": account.derivedAccounts.defaultWallet.address,
"wallet-root-address": account.derivedAccounts.walletRoot.address,
"preview-privacy?": true,
"signing-phrase": generateSigningPhrase(3),
"log-level": main_constants.LOG_LEVEL,
"latest-derived-path": 0,
"currency": "usd",
"networks/networks": @[],
"networks/current-network": "",
"wallet/visible-tokens": {},
"waku-enabled": true,
"appearance": 0,
"installation-id": installationId,
"current-user-status": %* {
"publicKey": account.derivedAccounts.whisper.publicKey,
"statusType": 1,
"clock": 0,
"text": ""
},
"profile-pictures-show-to": settings.PROFILE_PICTURES_SHOW_TO_EVERYONE,
"profile-pictures-visibility": settings.PROFILE_PICTURES_VISIBILITY_EVERYONE,
"url-unfurling-mode": int(settings.UrlUnfurlingMode.AlwaysAsk),
}
proc getAccountSettings(self: Service, accountId: string, installationId: string, displayName: string, withoutMnemonic: bool): JsonNode =
for acc in self.generatedAccounts:
if(acc.id == accountId):
return self.prepareAccountSettingsJsonObject(acc, installationId, displayName, withoutMnemonic)
if(self.importedAccount.isValid()):
if(self.importedAccount.id == accountId):
return self.prepareAccountSettingsJsonObject(self.importedAccount, installationId, displayName, withoutMnemonic)
# TODO: Remove after https://github.com/status-im/status-go/issues/4977
proc getDefaultNodeConfig*(self: Service, installationId: string, recoverAccount: bool): JsonNode = proc getDefaultNodeConfig*(self: Service, installationId: string, recoverAccount: bool): JsonNode =
let fleet = Fleet.ShardsTest let fleet = Fleet.ShardsTest
let dnsDiscoveryURL = "enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.test.shards.nodes.status.im" let dnsDiscoveryURL = "enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.test.shards.nodes.status.im"
@ -305,49 +186,8 @@ QtObject:
result["KeycardPairingDataFile"] = newJString(main_constants.KEYCARDPAIRINGDATAFILE) result["KeycardPairingDataFile"] = newJString(main_constants.KEYCARDPAIRINGDATAFILE)
result["ProcessBackedupMessages"] = newJBool(recoverAccount) result["ProcessBackedupMessages"] = newJBool(recoverAccount)
# TODO: Remove after https://github.com/status-im/status-go/issues/4977 # FIXME: remove this method, settings should be processed in status-go
proc getLoginNodeConfig(self: Service): JsonNode = # https://github.com/status-im/status-go/issues/5359
# To create appropriate NodeConfig for Login we set only params that maybe be set via env variables or cli flags
result = %*{}
# mandatory params
result["NetworkId"] = NETWORKS[0]{"chainId"}
result["DataDir"] = %* "./ethereum/mainnet"
result["KeyStoreDir"] = %* self.keyStoreDir.replace(main_constants.STATUSGODIR, "")
result["KeycardPairingDataFile"] = %* main_constants.KEYCARDPAIRINGDATAFILE
# other params
result["Networks"] = NETWORKS
result["UpstreamConfig"] = %* {
"URL": NETWORKS[0]{"rpcUrl"},
"Enabled": true,
}
result["ShhextConfig"] = %* {
"VerifyENSURL": NETWORKS[0]{"fallbackUrl"},
"VerifyTransactionURL": NETWORKS[0]{"fallbackUrl"}
}
result["WakuV2Config"] = %* {
"Port": WAKU_V2_PORT,
"UDPPort": WAKU_V2_PORT
}
result["WalletConfig"] = NODE_CONFIG["WalletConfig"]
result["TorrentConfig"] = %* {
"Port": TORRENT_CONFIG_PORT,
"DataDir": DEFAULT_TORRENT_CONFIG_DATADIR,
"TorrentDir": DEFAULT_TORRENT_CONFIG_TORRENTDIR
}
if main_constants.runtimeLogLevelSet():
result["RuntimeLogLevel"] = newJString(toStatusGoSupportedLogLevel(main_constants.LOG_LEVEL))
if STATUS_PORT != 0:
result["ListenAddr"] = newJString("0.0.0.0:" & $main_constants.STATUS_PORT)
proc addKeycardDetails(self: Service, kcInstance: string, settingsJson: var JsonNode, accountData: var JsonNode) = proc addKeycardDetails(self: Service, kcInstance: string, settingsJson: var JsonNode, accountData: var JsonNode) =
let keycardPairingJsonString = readFile(main_constants.KEYCARDPAIRINGDATAFILE) let keycardPairingJsonString = readFile(main_constants.KEYCARDPAIRINGDATAFILE)
let keycardPairingJsonObj = keycardPairingJsonString.parseJSON let keycardPairingJsonObj = keycardPairingJsonString.parseJSON
@ -383,7 +223,7 @@ QtObject:
proc buildCreateAccountRequest(self: Service, password: string, displayName: string, imagePath: string, imageCropRectangle: ImageCropRectangle): CreateAccountRequest = proc buildCreateAccountRequest(self: Service, password: string, displayName: string, imagePath: string, imageCropRectangle: ImageCropRectangle): CreateAccountRequest =
return CreateAccountRequest( return CreateAccountRequest(
backupDisabledDataDir: main_constants.STATUSGODIR, rootDataDir: main_constants.STATUSGODIR,
kdfIterations: KDF_ITERATIONS, kdfIterations: KDF_ITERATIONS,
password: hashPassword(password), password: hashPassword(password),
displayName: displayName, displayName: displayName,
@ -396,6 +236,7 @@ QtObject:
previewPrivacy: true, previewPrivacy: true,
torrentConfigEnabled: some(false), torrentConfigEnabled: some(false),
torrentConfigPort: some(TORRENT_CONFIG_PORT), torrentConfigPort: some(TORRENT_CONFIG_PORT),
keycardPairingDataFile: main_constants.KEYCARDPAIRINGDATAFILE,
walletSecretsConfig: self.buildWalletSecrets(), walletSecretsConfig: self.buildWalletSecrets(),
) )
@ -420,13 +261,57 @@ QtObject:
error "failed to create account or login", procName="createAccountAndLogin", errName = e.name, errDesription = e.msg error "failed to create account or login", procName="createAccountAndLogin", errName = e.name, errDesription = e.msg
return e.msg return e.msg
proc importAccountAndLogin*(self: Service, mnemonic: string, password: string, recoverAccount: bool, displayName: string, imagePath: string, imageCropRectangle: ImageCropRectangle): string = proc importAccountAndLogin*(self: Service,
mnemonic: string,
password: string,
recoverAccount: bool,
displayName: string,
imagePath: string,
imageCropRectangle: ImageCropRectangle,
keycardInstanceUID: string = "",
): string =
var request = RestoreAccountRequest(
mnemonic: mnemonic,
fetchBackup: recoverAccount,
createAccountRequest: self.buildCreateAccountRequest(password, displayName, imagePath, imageCropRectangle),
)
request.createAccountRequest.keycardInstanceUID = keycardInstanceUID
self.restoreAccountAndLogin(request)
proc restoreKeycardAccountAndLogin*(self: Service,
keycardData: KeycardEvent,
recoverAccount: bool,
displayName: string,
imagePath: string,
imageCropRectangle: ImageCropRectangle,
): string =
let keycard = KeycardData(
keyUid: keycardData.keyUid,
address: keycardData.masterKey.address,
whisperPrivateKey: keycardData.whisperKey.privateKey,
whisperPublicKey: keycardData.whisperKey.publicKey,
whisperAddress: keycardData.whisperKey.address,
walletPublicKey: keycardData.walletKey.publicKey,
walletAddress: keycardData.walletKey.address,
walletRootAddress: keycardData.walletRootKey.address,
eip1581Address: keycardData.eip1581Key.address,
encryptionPublicKey: keycardData.encryptionKey.publicKey,
)
var request = RestoreAccountRequest(
keycard: keycard,
fetchBackup: recoverAccount,
createAccountRequest: self.buildCreateAccountRequest("", displayName, imagePath, imageCropRectangle),
)
request.createAccountRequest.keycardInstanceUID = keycardData.instanceUid
return self.restoreAccountAndLogin(request)
proc restoreAccountAndLogin(self: Service, request: RestoreAccountRequest): string =
try: try:
let request = RestoreAccountRequest(
mnemonic: mnemonic,
fetchBackup: recoverAccount,
createAccountRequest: self.buildCreateAccountRequest(password, displayName, imagePath, imageCropRectangle),
)
let response = status_account.restoreAccountAndLogin(request) let response = status_account.restoreAccountAndLogin(request)
if not response.result.contains("error"): if not response.result.contains("error"):
@ -438,120 +323,11 @@ QtObject:
debug "Account saved succesfully" debug "Account saved succesfully"
return "" return ""
error "importAccountAndLogin status-go error: ", error error "restoreAccountAndLogin status-go error: ", error
return "importAccountAndLogin failed: " & error return "restoreAccountAndLogin failed: " & error
except Exception as e: except Exception as e:
error "failed to import account or login", procName="importAccountAndLogin", errName = e.name, errDesription = e.msg error "restore account failed", procName="restoreAccountAndLogin", errName = e.name, errDesription = e.msg
return e.msg
proc setupAccountKeycard*(self: Service, keycardData: KeycardEvent, displayName: string, useImportedAcc: bool,
recoverAccount: bool = false) =
try:
var keyUid = keycardData.keyUid
var address = keycardData.masterKey.address
var whisperPrivateKey = keycardData.whisperKey.privateKey
var whisperPublicKey = keycardData.whisperKey.publicKey
var whisperAddress = keycardData.whisperKey.address
var walletPublicKey = keycardData.walletKey.publicKey
var walletAddress = keycardData.walletKey.address
var walletRootAddress = keycardData.walletRootKey.address
var eip1581Address = keycardData.eip1581Key.address
var encryptionPublicKey = keycardData.encryptionKey.publicKey
if useImportedAcc:
keyUid = self.importedAccount.keyUid
address = self.importedAccount.address
whisperPublicKey = self.importedAccount.derivedAccounts.whisper.publicKey
whisperAddress = self.importedAccount.derivedAccounts.whisper.address
walletPublicKey = self.importedAccount.derivedAccounts.defaultWallet.publicKey
walletAddress = self.importedAccount.derivedAccounts.defaultWallet.address
walletRootAddress = self.importedAccount.derivedAccounts.walletRoot.address
eip1581Address = self.importedAccount.derivedAccounts.eip1581.address
encryptionPublicKey = self.importedAccount.derivedAccounts.encryption.publicKey
whisperPrivateKey = self.importedAccount.derivedAccounts.whisper.privateKey
if whisperPrivateKey.startsWith("0x"):
whisperPrivateKey = whisperPrivateKey[2 .. ^1]
let installationId = $genUUID()
let alias = generateAliasFromPk(whisperPublicKey)
var accountDataJson = %* {
"name": if displayName == "": alias else: displayName,
"display-name": displayName,
"address": address,
"key-uid": keyUid,
"kdfIterations": KDF_ITERATIONS,
}
self.setKeyStoreDir(keyUid)
let nodeConfigJson = self.getDefaultNodeConfig(installationId, recoverAccount)
let subaccountDataJson = %* [
{
"public-key": walletPublicKey,
"address": walletAddress,
"colorId": DEFAULT_CUSTOMIZATION_COLOR,
"wallet": true,
"path": PATH_DEFAULT_WALLET,
"name": DEFAULT_WALLET_ACCOUNT_NAME,
"derived-from": address,
"emoji": self.defaultWalletEmoji,
},
{
"public-key": whisperPublicKey,
"address": whisperAddress,
"name": if displayName == "": alias else: displayName,
"path": PATH_WHISPER,
"chat": true,
"derived-from": ""
}
]
var settingsJson = %* {
"key-uid": keyUid,
"public-key": whisperPublicKey,
"name": alias,
"display-name": displayName,
"address": address,
"eip1581-address": eip1581Address,
"dapps-address": walletAddress,
"wallet-root-address": walletRootAddress,
"preview-privacy?": true,
"signing-phrase": generateSigningPhrase(3),
"log-level": main_constants.LOG_LEVEL,
"latest-derived-path": 0,
"currency": "usd",
"networks/networks": @[],
"networks/current-network": "",
"wallet/visible-tokens": {},
"waku-enabled": true,
"appearance": 0,
"installation-id": installationId,
"current-user-status": {
"publicKey": whisperPublicKey,
"statusType": 1,
"clock": 0,
"text": ""
}
}
self.addKeycardDetails(keycardData.instanceUID, settingsJson, accountDataJson)
if(accountDataJson.isNil or subaccountDataJson.isNil or settingsJson.isNil or
nodeConfigJson.isNil):
let description = "at least one json object is not prepared well"
error "error: ", procName="setupAccountKeycard", errDesription = description
return
self.loggedInAccount = self.saveKeycardAccountAndLogin(chatKey = whisperPrivateKey,
password = encryptionPublicKey,
accountDataJson,
subaccountDataJson,
settingsJson,
nodeConfigJson)
self.setLocalAccountSettingsFile()
except Exception as e:
error "error: ", procName="setupAccount", errName = e.name, errDesription = e.msg
proc createAccountFromPrivateKey*(self: Service, privateKey: string): GeneratedAccountDto = proc createAccountFromPrivateKey*(self: Service, privateKey: string): GeneratedAccountDto =
if privateKey.len == 0: if privateKey.len == 0:
@ -610,27 +386,6 @@ QtObject:
data.error = e.msg data.error = e.msg
self.events.emit(SIGNAL_DERIVED_ADDRESSES_FROM_NOT_IMPORTED_MNEMONIC_FETCHED, data) self.events.emit(SIGNAL_DERIVED_ADDRESSES_FROM_NOT_IMPORTED_MNEMONIC_FETCHED, data)
proc importMnemonic*(self: Service, mnemonic: string): string =
if mnemonic.len == 0:
return "empty mnemonic"
try:
let response = status_account.multiAccountImportMnemonic(mnemonic)
self.importedAccount = toGeneratedAccountDto(response.result)
if (self.accounts.contains(self.importedAccount.keyUid)):
return ACCOUNT_ALREADY_EXISTS_ERROR
let responseDerived = status_account.deriveAccounts(self.importedAccount.id, PATHS)
self.importedAccount.derivedAccounts = toDerivedAccounts(responseDerived.result)
self.importedAccount.alias= generateAliasFromPk(self.importedAccount.derivedAccounts.whisper.publicKey)
if (not self.importedAccount.isValid()):
return "imported account is not valid"
except Exception as e:
error "error: ", procName="importMnemonic", errName = e.name, errDesription = e.msg
return e.msg
proc verifyAccountPassword*(self: Service, account: string, password: string): bool = proc verifyAccountPassword*(self: Service, account: string, password: string): bool =
try: try:
let response = status_account.verifyAccountPassword(account, utils.hashPassword(password), self.keyStoreDir) let response = status_account.verifyAccountPassword(account, utils.hashPassword(password), self.keyStoreDir)
@ -657,11 +412,13 @@ QtObject:
except Exception as e: except Exception as e:
error "error: ", procName="verifyDatabasePassword", errName = e.name, errDesription = e.msg error "error: ", procName="verifyDatabasePassword", errName = e.name, errDesription = e.msg
proc doLogin(self: Service, account: AccountDto, passwordHash: string) = proc doLogin(self: Service, account: AccountDto, passwordHash: string, chatPrivateKey: string = "", mnemonic: string = "") =
var request = LoginAccountRequest( var request = LoginAccountRequest(
keyUid: account.keyUid, keyUid: account.keyUid,
kdfIterations: account.kdfIterations, kdfIterations: account.kdfIterations,
passwordHash: passwordHash, passwordHash: passwordHash,
keycardWhisperPrivateKey: chatPrivateKey,
mnemonic: mnemonic,
walletSecretsConfig: self.buildWalletSecrets(), walletSecretsConfig: self.buildWalletSecrets(),
bandwidthStatsEnabled: true, bandwidthStatsEnabled: true,
) )
@ -678,8 +435,9 @@ QtObject:
debug "account logged in" debug "account logged in"
self.setLocalAccountSettingsFile() self.setLocalAccountSettingsFile()
proc login*(self: Service, account: AccountDto, hashedPassword: string) = proc login*(self: Service, account: AccountDto, hashedPassword: string, chatPrivateKey: string = "", mnemonic: string = "") =
try: try:
# WARNING: Is this keystore migration still needed?
let keyStoreDir = joinPath(main_constants.ROOTKEYSTOREDIR, account.keyUid) & main_constants.sep let keyStoreDir = joinPath(main_constants.ROOTKEYSTOREDIR, account.keyUid) & main_constants.sep
if not dirExists(keyStoreDir): if not dirExists(keyStoreDir):
os.createDir(keyStoreDir) os.createDir(keyStoreDir)
@ -689,30 +447,33 @@ QtObject:
self.setKeyStoreDir(account.keyUid) self.setKeyStoreDir(account.keyUid)
let isOldHashPassword = self.verifyDatabasePassword(account.keyUid, hashedPasswordToUpperCase(hashedPassword)) if mnemonic == "":
if isOldHashPassword: let oldHashedPassword = hashedPasswordToUpperCase(hashedPassword)
debug "database reencryption scheduled" if self.verifyDatabasePassword(account.keyUid, oldHashedPassword):
self.scheduleReencrpytion(account, hashedPassword, timeout = 1000)
return
# Save tmp properties so that we can login after the timer self.doLogin(account, hashedPassword, chatPrivateKey, mnemonic)
self.tmpAccount = account
self.tmpHashedPassword = hashedPassword
# Start a 1 second timer for the loading screen to appear
let arg = TimerTaskArg(
tptr: timerTask,
vptr: cast[ByteAddress](self.vptr),
slot: "onWaitForReencryptionTimeout",
timeoutInMilliseconds: 1000
)
self.threadpool.start(arg)
return
self.doLogin(account, hashedPassword)
except Exception as e: except Exception as e:
error "login failed", errName = e.name, errDesription = e.msg error "login failed", errName = e.name, errDesription = e.msg
self.events.emit(SIGNAL_LOGIN_ERROR, LoginErrorArgs(error: e.msg)) self.events.emit(SIGNAL_LOGIN_ERROR, LoginErrorArgs(error: e.msg))
proc scheduleReencrpytion(self: Service, account: AccountDto, hashedPassword: string, timeout: int = 1000) =
debug "database reencryption scheduled"
# Save tmp properties so that we can login after the timer
self.tmpAccount = account
self.tmpHashedPassword = hashedPassword
let arg = TimerTaskArg(
tptr: timerTask,
vptr: cast[ByteAddress](self.vptr),
slot: "onWaitForReencryptionTimeout",
timeoutInMilliseconds: timeout
)
self.threadpool.start(arg)
proc onWaitForReencryptionTimeout(self: Service, response: string) {.slot.} = proc onWaitForReencryptionTimeout(self: Service, response: string) {.slot.} =
debug "starting database reencryption" debug "starting database reencryption"
@ -727,34 +488,6 @@ QtObject:
self.tmpAccount = AccountDto() self.tmpAccount = AccountDto()
self.tmpHashedPassword = "" self.tmpHashedPassword = ""
proc loginAccountKeycard*(self: Service, accToBeLoggedIn: AccountDto, keycardData: KeycardEvent): string =
try:
self.setKeyStoreDir(keycardData.keyUid)
var accountDataJson = %* {
"key-uid": accToBeLoggedIn.keyUid,
}
let nodeConfigJson = self.getLoginNodeConfig()
let response = status_account.loginWithKeycard(keycardData.whisperKey.privateKey,
keycardData.encryptionKey.publicKey,
accountDataJson,
nodeConfigJson)
var error = "response doesn't contain \"error\""
if(response.result.contains("error")):
error = response.result["error"].getStr
if error == "":
debug "Account logged in succesfully"
# this should be fetched later from waku
self.loggedInAccount = accToBeLoggedIn
self.setLocalAccountSettingsFile()
return
except Exception as e:
error "keycard login failed", procName="loginAccountKeycard", errName = e.name, errDesription = e.msg
return e.msg
proc convertRegularProfileKeypairToKeycard*(self: Service, keycardUid, currentPassword: string, newPassword: string) = proc convertRegularProfileKeypairToKeycard*(self: Service, keycardUid, currentPassword: string, newPassword: string) =
var accountDataJson = %* { var accountDataJson = %* {
"key-uid": self.getLoggedInAccount().keyUid, "key-uid": self.getLoggedInAccount().keyUid,
@ -816,7 +549,7 @@ QtObject:
if(errMsg.len == 0): if(errMsg.len == 0):
result = true result = true
else: else:
error "error: ", procName="onConvertKeycardProfileKeypairToRegular", errDesription = errMsg error "failed to convert keycard account", procName="onConvertKeycardProfileKeypairToRegular", errDesription = errMsg
except Exception as e: except Exception as e:
error "error handilng migrated keypair response", procName="onConvertKeycardProfileKeypairToRegular", errDesription=e.msg error "error handilng migrated keypair response", procName="onConvertKeycardProfileKeypairToRegular", errDesription=e.msg
self.events.emit(SIGNAL_CONVERTING_PROFILE_KEYPAIR, ResultArgs(success: result)) self.events.emit(SIGNAL_CONVERTING_PROFILE_KEYPAIR, ResultArgs(success: result))

View File

@ -1,4 +1,3 @@
import json
import ../../../backend/accounts as status_account import ../../../backend/accounts as status_account
import ../../common/conversion import ../../common/conversion
@ -42,9 +41,6 @@ proc compressCommunityKey*(publicKey: string): string =
except Exception as e: except Exception as e:
echo "error: `compressCommunityKey` " & $e.name & " msg: " & $e.msg echo "error: `compressCommunityKey` " & $e.name & " msg: " & $e.msg
proc generateAliasFromPk*(publicKey: string): string =
return status_account.generateAlias(publicKey).result.getStr
proc isAlias*(value: string): bool = proc isAlias*(value: string): bool =
return status_account.isAlias(value) return status_account.isAlias(value)
@ -57,4 +53,4 @@ proc changeCommunityKeyCompression*(publicKey: string): string =
else: else:
# is 33-bytes # is 33-bytes
let uncompressedKey = decompressCommunityKey(publicKey) let uncompressedKey = decompressCommunityKey(publicKey)
return compressPk(uncompressedKey) return compressPk(uncompressedKey)

View File

@ -13,8 +13,6 @@ export response_type
logScope: logScope:
topics = "rpc-accounts" topics = "rpc-accounts"
const NUMBER_OF_ADDRESSES_TO_GENERATE = 1
const MNEMONIC_PHRASE_LENGTH = 12
const PK_LENGTH_0X_INCLUDED = 132 const PK_LENGTH_0X_INCLUDED = 132
const GENERATED* = "generated" const GENERATED* = "generated"
@ -132,22 +130,6 @@ proc updateAccount*(name, address, path: string, publicKey, keyUid, accountType,
] ]
return core.callPrivateRPC("accounts_saveAccount", payload) return core.callPrivateRPC("accounts_saveAccount", payload)
proc generateAddresses*(paths: seq[string]): RpcResponse[JsonNode] =
let payload = %* {
"n": NUMBER_OF_ADDRESSES_TO_GENERATE,
"mnemonicPhraseLength": MNEMONIC_PHRASE_LENGTH,
"bip39Passphrase": "",
"paths": paths
}
try:
let response = status_go.multiAccountGenerateAndDeriveAddresses($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "generateAddresses", exception=e.msg
raise newException(RpcException, e.msg)
proc decompressPk*(publicKey: string): RpcResponse[string] = proc decompressPk*(publicKey: string): RpcResponse[string] =
discard discard
if publicKey.startsWith("0x04") and publicKey.len == PK_LENGTH_0X_INCLUDED: if publicKey.startsWith("0x04") and publicKey.len == PK_LENGTH_0X_INCLUDED:
@ -221,20 +203,6 @@ proc getRandomMnemonic*(): RpcResponse[JsonNode] =
let payload = %* [] let payload = %* []
return core.callPrivateRPC("accounts_getRandomMnemonic", payload) return core.callPrivateRPC("accounts_getRandomMnemonic", payload)
proc multiAccountImportMnemonic*(mnemonic: string): RpcResponse[JsonNode] =
let payload = %* {
"mnemonicPhrase": mnemonic,
"Bip39Passphrase": ""
}
try:
let response = status_go.multiAccountImportMnemonic($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "multiAccountImportMnemonic", exception=e.msg
raise newException(RpcException, e.msg)
## Imports a new mnemonic and creates local keystore file. ## Imports a new mnemonic and creates local keystore file.
proc importMnemonic*(mnemonic, password: string): proc importMnemonic*(mnemonic, password: string):
RpcResponse[JsonNode] = RpcResponse[JsonNode] =
@ -290,20 +258,6 @@ proc createAccountFromPrivateKey*(privateKey: string): RpcResponse[JsonNode] =
error "error doing rpc request", methodName = "createAccountFromPrivateKey", exception=e.msg error "error doing rpc request", methodName = "createAccountFromPrivateKey", exception=e.msg
raise newException(RpcException, e.msg) raise newException(RpcException, e.msg)
proc deriveAccounts*(accountId: string, paths: seq[string]): RpcResponse[JsonNode] =
let payload = %* {
"accountID": accountId,
"paths": paths
}
try:
let response = status_go.multiAccountDeriveAddresses($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "deriveAccounts", exception=e.msg
raise newException(RpcException, e.msg)
proc openedAccounts*(path: string): RpcResponse[JsonNode] = proc openedAccounts*(path: string): RpcResponse[JsonNode] =
try: try:
let response = status_go.openAccounts(path) let response = status_go.openAccounts(path)
@ -342,16 +296,6 @@ proc restoreAccountAndLogin*(request: RestoreAccountRequest): RpcResponse[JsonNo
error "error doing rpc request", methodName = "restoreAccountAndLogin", exception=e.msg error "error doing rpc request", methodName = "restoreAccountAndLogin", exception=e.msg
raise newException(RpcException, e.msg) raise newException(RpcException, e.msg)
proc saveAccountAndLoginWithKeycard*(chatKey, password: string, account, subaccounts, settings, config: JsonNode):
RpcResponse[JsonNode] =
try:
let response = status_go.saveAccountAndLoginWithKeycard($account, password, $settings, $config, $subaccounts, chatKey)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "saveAccountAndLogin", exception=e.msg
raise newException(RpcException, e.msg)
proc convertRegularProfileKeypairToKeycard*(account: JsonNode, settings: JsonNode, keycardUid: string, password: string, newPassword: string): proc convertRegularProfileKeypairToKeycard*(account: JsonNode, settings: JsonNode, keycardUid: string, password: string, newPassword: string):
RpcResponse[JsonNode] = RpcResponse[JsonNode] =
try: try:
@ -380,14 +324,6 @@ proc loginAccount*(request: LoginAccountRequest): RpcResponse[JsonNode] =
error "loginAccount failed", exception=e.msg error "loginAccount failed", exception=e.msg
raise newException(RpcException, e.msg) raise newException(RpcException, e.msg)
proc loginWithKeycard*(chatKey, password: string, account, confNode: JsonNode): RpcResponse[JsonNode] =
try:
let response = status_go.loginWithKeycard($account, password, chatKey, $confNode)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "loginWithKeycard", exception=e.msg
raise newException(RpcException, e.msg)
proc verifyAccountPassword*(address: string, hashedPassword: string, keystoreDir: string): proc verifyAccountPassword*(address: string, hashedPassword: string, keystoreDir: string):
RpcResponse[JsonNode] = RpcResponse[JsonNode] =
try: try:

@ -1 +1 @@
Subproject commit d38b1147f8b4d0c4abdb1dbf353aff36454e02ed Subproject commit 0fdd7d8def22e64018fe2a47b9c0d98da387c6bc

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit ee2330fe5d4233a7d8b105420c2b93284ad161f3 Subproject commit 49eaabaca5100368c5b39fb8c107aad2535371e5