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:
parent
8cca2664e4
commit
c8bc68b96c
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
|
@ -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()
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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():
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
@ -1 +1 @@
|
||||||
Subproject commit ee2330fe5d4233a7d8b105420c2b93284ad161f3
|
Subproject commit 49eaabaca5100368c5b39fb8c107aad2535371e5
|
Loading…
Reference in New Issue