feat(@desktop/wallet-sync): accounts syncing part 1
This commit is contained in:
parent
1a919f586f
commit
69bf8c0e53
|
@ -10,8 +10,8 @@ import ../../../../app_service/service/activity_center/dto/[notification]
|
|||
import ../../../../app_service/service/contacts/dto/[contacts, status_update]
|
||||
import ../../../../app_service/service/devices/dto/[installation]
|
||||
import ../../../../app_service/service/settings/dto/[settings]
|
||||
import ../../../../app_service/service/saved_address/[dto]
|
||||
import ../../../../app_service/service/wallet_account/[key_pair_dto]
|
||||
import ../../../../app_service/service/saved_address/dto as saved_address_dto
|
||||
import ../../../../app_service/service/wallet_account/[dto, key_pair_dto]
|
||||
|
||||
type MessageSignal* = ref object of Signal
|
||||
bookmarks*: seq[BookmarkDto]
|
||||
|
@ -35,6 +35,7 @@ type MessageSignal* = ref object of Signal
|
|||
savedAddresses*: seq[SavedAddressDto]
|
||||
keycards*: seq[KeyPairDto]
|
||||
keycardActions*: seq[KeycardActionDto]
|
||||
walletAccounts*: seq[WalletAccountDto]
|
||||
|
||||
type MessageDeliveredSignal* = ref object of Signal
|
||||
chatId*: string
|
||||
|
@ -141,5 +142,9 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
|
|||
for jsonKc in event["event"]["keycardActions"]:
|
||||
signal.keycardActions.add(jsonKc.toKeycardActionDto())
|
||||
|
||||
if event["event"]{"accounts"} != nil:
|
||||
for jsonAcc in event["event"]["accounts"]:
|
||||
signal.walletAccounts.add(jsonAcc.toWalletAccountDto())
|
||||
|
||||
result = signal
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ type SignalType* {.pure.} = enum
|
|||
WakuFetchingBackupProgress = "waku.fetching.backup.progress"
|
||||
WakuBackedUpProfile = "waku.backedup.profile"
|
||||
WakuBackedUpSettings = "waku.backedup.settings"
|
||||
WakuBackedUpWalletAccount = "waku.backedup.wallet-account"
|
||||
WakuBackedUpKeycards = "waku.backedup.keycards"
|
||||
LocalPairing = "localPairing"
|
||||
Unknown
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import json
|
||||
import base
|
||||
|
||||
import ../../../../app_service/service/wallet_account/[dto]
|
||||
|
||||
type WakuBackedUpWalletAccountsSignal* = ref object of Signal
|
||||
account*: WalletAccountDto
|
||||
|
||||
proc fromEvent*(T: type WakuBackedUpWalletAccountsSignal, event: JsonNode): WakuBackedUpWalletAccountsSignal =
|
||||
result = WakuBackedUpWalletAccountsSignal()
|
||||
|
||||
if event["event"]{"backedUpWalletAccount"} != nil:
|
||||
result.account = event["event"]["backedUpWalletAccount"].toWalletAccountDto()
|
|
@ -116,6 +116,7 @@ QtObject:
|
|||
of SignalType.WakuFetchingBackupProgress: WakuFetchingBackupProgressSignal.fromEvent(jsonSignal)
|
||||
of SignalType.WakuBackedUpProfile: WakuBackedUpProfileSignal.fromEvent(jsonSignal)
|
||||
of SignalType.WakuBackedUpSettings: WakuBackedUpSettingsSignal.fromEvent(jsonSignal)
|
||||
of SignalType.WakuBackedUpWalletAccount: WakuBackedUpWalletAccountsSignal.fromEvent(jsonSignal)
|
||||
of SignalType.WakuBackedUpKeycards: WakuBackedUpKeycardsSignal.fromEvent(jsonSignal)
|
||||
# pairing
|
||||
of SignalType.LocalPairing: LocalPairingSignal.fromEvent(jsonSignal)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import ./remote_signals/[base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages,
|
||||
peerstats, signal_type, stats, wallet, whisper_filter, update_available, status_updates, waku_backed_up_profile,
|
||||
waku_backed_up_settings, waku_backed_up_keycards, waku_fetching_backup_progress, pairing]
|
||||
waku_backed_up_settings, waku_backed_up_wallet_accounts, waku_backed_up_keycards, waku_fetching_backup_progress, pairing]
|
||||
|
||||
export base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats,
|
||||
signal_type, stats, wallet, whisper_filter, update_available, status_updates, waku_backed_up_profile,
|
||||
waku_backed_up_settings, waku_backed_up_keycards, waku_fetching_backup_progress, pairing
|
||||
waku_backed_up_settings, waku_backed_up_wallet_accounts, waku_backed_up_keycards, waku_fetching_backup_progress, pairing
|
|
@ -268,7 +268,8 @@ proc buildKeycardList(self: Module) =
|
|||
## If all created keycards for certain keypair are locked, then we need to display that item as locked.
|
||||
item.setLocked(self.areAllKnownKeycardsLockedForKeypair(item.getKeyUid()))
|
||||
items.add(item)
|
||||
self.view.setKeycardItems(items)
|
||||
if items.len > 0:
|
||||
self.view.setKeycardItems(items)
|
||||
|
||||
method onLoggedInUserImageChanged*(self: Module) =
|
||||
self.view.keycardModel().setImage(singletonInstance.userProfile.getPubKey(), singletonInstance.userProfile.getIcon())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import tables, json, sequtils, sugar, strutils
|
||||
import tables, json, strformat, sequtils, sugar, strutils
|
||||
|
||||
include ../../common/json_utils
|
||||
|
||||
|
@ -104,6 +104,7 @@ type
|
|||
lastUsedDerivationIndex*: int
|
||||
hasBalanceCache*: bool
|
||||
hasMarketValuesCache*: bool
|
||||
removed*: bool # needs for synchronization
|
||||
|
||||
proc newDto*(
|
||||
name: string,
|
||||
|
@ -149,10 +150,31 @@ proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
|
|||
discard jsonObj.getProp("derived-from", result.derivedfrom)
|
||||
discard jsonObj.getProp("keypair-name", result.keypairName)
|
||||
discard jsonObj.getProp("last-used-derivation-index", result.lastUsedDerivationIndex)
|
||||
discard jsonObj.getProp("removed", result.removed)
|
||||
result.assetsLoading = true
|
||||
result.hasBalanceCache = false
|
||||
result.hasMarketValuesCache = false
|
||||
|
||||
proc `$`*(self: WalletAccountDto): string =
|
||||
result = fmt"""WalletAccountDto[
|
||||
name: {self.name},
|
||||
address: {self.address},
|
||||
mixedcaseAddress: {self.mixedcaseAddress},
|
||||
keyUid: {self.keyUid},
|
||||
path: {self.path},
|
||||
color: {self.color},
|
||||
publicKey: {self.publicKey},
|
||||
walletType: {self.walletType},
|
||||
isChat: {self.isChat},
|
||||
emoji: {self.emoji},
|
||||
derivedfrom: {self.derivedfrom},
|
||||
keypairName: {self.keypairName},
|
||||
lastUsedDerivationIndex: {self.lastUsedDerivationIndex},
|
||||
hasBalanceCache: {self.hasBalanceCache},
|
||||
hasMarketValuesCache: {self.hasMarketValuesCache},
|
||||
removed: {self.removed}
|
||||
]"""
|
||||
|
||||
proc getCurrencyBalance*(self: BalanceDto, currencyPrice: float64): float64 =
|
||||
return self.balance * currencyPrice
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ QtObject:
|
|||
proc buildAllTokens(self: Service, accounts: seq[string], store: bool)
|
||||
proc checkRecentHistory*(self: Service)
|
||||
proc startWallet(self: Service)
|
||||
proc handleWalletAccount(self: Service, account: WalletAccountDto)
|
||||
proc handleKeycardActions(self: Service, keycardActions: seq[KeycardActionDto])
|
||||
proc handleKeycardsState(self: Service, keycardsState: seq[KeyPairDto])
|
||||
proc getAllKnownKeycards*(self: Service): seq[KeyPairDto]
|
||||
|
@ -177,6 +178,15 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "error: ", procName="getAccountsByKeyUID", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc verifyKeystoreFileForAccount*(self: Service, account, password: string): bool =
|
||||
try:
|
||||
let hashedPassword = utils.hashPassword(password)
|
||||
let response = status_go_accounts.verifyKeystoreFileForAccount(account, hashedPassword)
|
||||
return response.result.getBool
|
||||
except Exception as e:
|
||||
error "error: ", procName="verifyKeystoreFileForAccount", errName = e.name, errDesription = e.msg
|
||||
return false
|
||||
|
||||
proc setEnsName(self: Service, account: WalletAccountDto) =
|
||||
let chainId = self.networkService.getNetworkForEns().chainId
|
||||
try:
|
||||
|
@ -193,14 +203,17 @@ QtObject:
|
|||
(cmpIgnoreCase(x.derivedFrom, account.derivedFrom) == 0))
|
||||
|
||||
proc setRelatedAccountsForAllAccounts(self: Service, derivedFrom: string) =
|
||||
if derivedFrom.len == 0:
|
||||
return
|
||||
for wAcc in self.walletAccounts.mvalues:
|
||||
if not wAcc.derivedFrom.isEmptyOrWhitespace and
|
||||
cmpIgnoreCase(wAcc.derivedFrom, derivedFrom) == 0:
|
||||
self.setRelatedAccountsToAccount(wAcc)
|
||||
|
||||
proc storeAccount(self: Service, account: WalletAccountDto) =
|
||||
# updating related accounts for already added accounts
|
||||
self.setRelatedAccountsForAllAccounts(account.derivedFrom)
|
||||
proc storeAccount(self: Service, account: WalletAccountDto, updateRelatedAccounts = true) =
|
||||
if updateRelatedAccounts:
|
||||
# updating related accounts for already added accounts
|
||||
self.setRelatedAccountsForAllAccounts(account.derivedFrom)
|
||||
# add new account to store
|
||||
self.walletAccounts[account.address] = account
|
||||
|
||||
|
@ -291,6 +304,9 @@ QtObject:
|
|||
if settingsField.name == KEY_CURRENCY:
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED, CurrencyUpdated())
|
||||
|
||||
if receivedData.walletAccounts.len > 0:
|
||||
for acc in receivedData.walletAccounts:
|
||||
self.handleWalletAccount(acc)
|
||||
self.handleKeycardsState(receivedData.keycards)
|
||||
self.handleKeycardActions(receivedData.keycardActions)
|
||||
|
||||
|
@ -336,7 +352,7 @@ QtObject:
|
|||
error "error: ", errDescription
|
||||
return
|
||||
|
||||
proc addNewAccountToLocalStore(self: Service) =
|
||||
proc addNewAccountToLocalStoreAndNotify(self: Service) =
|
||||
let accounts = self.fetchAccounts()
|
||||
var newAccount: WalletAccountDto
|
||||
var found = false
|
||||
|
@ -367,6 +383,16 @@ QtObject:
|
|||
self.setRelatedAccountsForAllAccounts(removedAcc.derivedFrom)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountDeleted(address: address))
|
||||
|
||||
proc updateAccountFromLocalStoreAndNotify(self: Service, address, name, color, emoji: string) =
|
||||
if not self.walletAccountsContainsAddress(address):
|
||||
return
|
||||
var account = self.getAccountByAddress(address)
|
||||
account.name = name
|
||||
account.color = color
|
||||
account.emoji = emoji
|
||||
self.storeAccount(account, updateRelatedAccounts = false)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, WalletAccountUpdated(account: account))
|
||||
|
||||
## if password is not provided local keystore file won't be created
|
||||
proc addWalletAccount*(self: Service, password: string, doPasswordHashing: bool, name, keyPairName, address, path: string,
|
||||
lastUsedDerivationIndex: int, rootWalletMasterKey, publicKey, keyUid, accountType, color, emoji: string): string =
|
||||
|
@ -384,7 +410,7 @@ QtObject:
|
|||
if not response.error.isNil:
|
||||
error "status-go error", procName="addWalletAccount", errCode=response.error.code, errDesription=response.error.message
|
||||
return response.error.message
|
||||
self.addNewAccountToLocalStore()
|
||||
self.addNewAccountToLocalStoreAndNotify()
|
||||
return ""
|
||||
except Exception as e:
|
||||
error "error: ", procName="addWalletAccount", errName=e.name, errDesription=e.msg
|
||||
|
@ -490,10 +516,7 @@ QtObject:
|
|||
if not response.error.isNil:
|
||||
error "status-go error", procName="updateWalletAccount", errCode=response.error.code, errDesription=response.error.message
|
||||
return false
|
||||
account.name = accountName
|
||||
account.color = color
|
||||
account.emoji = emoji
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, WalletAccountUpdated(account: account))
|
||||
self.updateAccountFromLocalStoreAndNotify(address, accountName, color, emoji)
|
||||
return true
|
||||
except Exception as e:
|
||||
error "error: ", procName="updateWalletAccount", errName=e.name, errDesription=e.msg
|
||||
|
@ -854,6 +877,15 @@ QtObject:
|
|||
error "error: ", procName="deleteKeycard", errName = e.name, errDesription = e.msg
|
||||
return false
|
||||
|
||||
proc handleWalletAccount(self: Service, account: WalletAccountDto) =
|
||||
if account.removed:
|
||||
self.removeAccountFromLocalStoreAndNotify(account.address)
|
||||
else:
|
||||
if self.walletAccountsContainsAddress(account.address):
|
||||
self.updateAccountFromLocalStoreAndNotify(account.address, account.name, account.color, account.emoji)
|
||||
else:
|
||||
self.addNewAccountToLocalStoreAndNotify()
|
||||
|
||||
proc handleKeycardActions(self: Service, keycardActions: seq[KeycardActionDto]) =
|
||||
if keycardActions.len == 0:
|
||||
return
|
||||
|
|
|
@ -29,7 +29,7 @@ proc deleteAccount*(address: string, password: string): RpcResponse[JsonNode] {.
|
|||
let payload = %* [address, password]
|
||||
return core.callPrivateRPC("accounts_deleteAccount", payload)
|
||||
|
||||
## Adds a new account and creates a Keystore file if password is provided, otherwise it only creates a new account
|
||||
## Adds a new account and creates a Keystore file if password is provided, otherwise it only creates a new account. Notifies paired devices.
|
||||
proc addAccount*(password, name, keyPairName, address, path: string, lastUsedDerivationIndex: int, rootWalletMasterKey, publicKey,
|
||||
keyUid, accountType, color, emoji: string):
|
||||
RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
|
@ -49,7 +49,7 @@ proc addAccount*(password, name, keyPairName, address, path: string, lastUsedDer
|
|||
"color": color,
|
||||
#"hidden" present on the status-go side, but we don't use it
|
||||
"derived-from": rootWalletMasterKey,
|
||||
#"clock" we leave this empty, if needed should be set on the status-go side
|
||||
#"clock" we leave this empty, set on the status-go side
|
||||
#"removed" present on the status-go side, used for synchronization, no need to set it here
|
||||
"keypair-name": keyPairName,
|
||||
"last-used-derivation-index": lastUsedDerivationIndex
|
||||
|
@ -57,14 +57,14 @@ proc addAccount*(password, name, keyPairName, address, path: string, lastUsedDer
|
|||
]
|
||||
return core.callPrivateRPC("accounts_addAccount", payload)
|
||||
|
||||
## Adds a new account without creating a Keystore file
|
||||
## Adds a new account without creating a Keystore file and notifies paired devices
|
||||
proc addAccountWithoutKeystoreFileCreation*(name, keyPairName, address, path: string, lastUsedDerivationIndex: int, rootWalletMasterKey, publicKey,
|
||||
keyUid, accountType, color, emoji: string):
|
||||
RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return addAccount(password = "", name, keyPairName, address, path, lastUsedDerivationIndex, rootWalletMasterKey, publicKey,
|
||||
keyUid, accountType, color, emoji)
|
||||
|
||||
## Updates either regular or keycard account, without interaction to a Keystore file
|
||||
## Updates either regular or keycard account, without interaction to a Keystore file and notifies paired devices
|
||||
proc updateAccount*(name, keyPairName, address, path: string, lastUsedDerivationIndex: int, rootWalletMasterKey, publicKey,
|
||||
keyUid, accountType, color, emoji: string, walletDefaultAccount: bool, chatDefaultAccount: bool):
|
||||
RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
|
@ -83,7 +83,7 @@ proc updateAccount*(name, keyPairName, address, path: string, lastUsedDerivation
|
|||
"color": color,
|
||||
#"hidden" present on the status-go side, but we don't use it
|
||||
"derived-from": rootWalletMasterKey,
|
||||
#"clock" we leave this empty, if needed should be set on the status-go side
|
||||
#"clock" we leave this empty, set on the status-go side
|
||||
#"removed" present on the status-go side, used for synchronization, no need to set it here
|
||||
"keypair-name": keyPairName,
|
||||
"last-used-derivation-index": lastUsedDerivationIndex
|
||||
|
@ -408,4 +408,8 @@ proc getAddressDetails*(address: string,): RpcResponse[JsonNode] {.raises: [Exce
|
|||
|
||||
proc verifyPassword*(password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [password]
|
||||
return core.callPrivateRPC("accounts_verifyPassword", payload)
|
||||
return core.callPrivateRPC("accounts_verifyPassword", payload)
|
||||
|
||||
proc verifyKeystoreFileForAccount*(address, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [address, password]
|
||||
return core.callPrivateRPC("accounts_verifyKeystoreFileForAccount", payload)
|
Loading…
Reference in New Issue