chore(@desktop/syncing): keycards syncing improvements part 2/2
Handling keycards related syncing improvements done on the status-go side. Closes: #11268
This commit is contained in:
parent
d7aa0582be
commit
1561b170e4
|
@ -36,7 +36,6 @@ type MessageSignal* = ref object of Signal
|
|||
verificationRequests*: seq[VerificationRequest]
|
||||
savedAddresses*: seq[SavedAddressDto]
|
||||
keypairs*: seq[KeypairDto]
|
||||
# keycardActions*: seq[KeycardActionDto] //TODO: will be removed in the second part of synchronization improvements
|
||||
watchOnlyAccounts*: seq[WalletAccountDto]
|
||||
|
||||
type MessageDeliveredSignal* = ref object of Signal
|
||||
|
@ -148,11 +147,6 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
|
|||
for jsonKc in e["keypairs"]:
|
||||
signal.keypairs.add(jsonKc.toKeypairDto())
|
||||
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
# if e.contains("keycardActions"):
|
||||
# for jsonKc in e["keycardActions"]:
|
||||
# signal.keycardActions.add(jsonKc.toKeycardActionDto())
|
||||
|
||||
if e.contains("watchOnlyAccounts"):
|
||||
for jsonAcc in e["watchOnlyAccounts"]:
|
||||
signal.watchOnlyAccounts.add(jsonAcc.toWalletAccountDto())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, Tables, sequtils, sugar
|
||||
import NimQml, Tables, sequtils, strutils, sugar
|
||||
|
||||
import ../../../../global/global_singleton
|
||||
import ../../../../core/eventemitter
|
||||
|
@ -83,6 +83,18 @@ proc switchAccount*(self: Module, accountIndex: int) =
|
|||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("browserSectionCurrentAccount", newQVariant(self.view))
|
||||
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
let args = KeypairArgs(e)
|
||||
let walletAccount = self.controller.getWalletAccount(self.currentAccountIndex)
|
||||
if walletAccount.isNil:
|
||||
self.switchAccount(0)
|
||||
return
|
||||
for acc in args.keypair.accounts:
|
||||
if cmpIgnoreCase(acc.address, walletAccount.address) == 0:
|
||||
return
|
||||
self.switchAccount(0)
|
||||
self.view.connectedAccountDeleted()
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
if(self.view.isAddressCurrentAccount(AccountArgs(e).account.address)):
|
||||
self.switchAccount(0)
|
||||
|
|
|
@ -73,7 +73,7 @@ method load*(self: Module) =
|
|||
let signingPhrase = self.controller.getSigningPhrase()
|
||||
let link = self.controller.getNetwork().blockExplorerUrl & "/tx/"
|
||||
self.view.load(link, signingPhrase)
|
||||
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args):
|
||||
self.view.emitChainIdChanged()
|
||||
self.controller.fixPreferredName(true)
|
||||
|
@ -85,15 +85,15 @@ method viewDidLoad*(self: Module) =
|
|||
# add registered ens usernames
|
||||
let registeredEnsUsernames = self.controller.getAllMyEnsUsernames(includePendingEnsUsernames = false)
|
||||
for dto in registeredEnsUsernames:
|
||||
let item = Item(chainId: dto.chainId,
|
||||
ensUsername: dto.username,
|
||||
let item = Item(chainId: dto.chainId,
|
||||
ensUsername: dto.username,
|
||||
isPending: false)
|
||||
self.view.model().addItem(item)
|
||||
# add pending ens usernames
|
||||
let pendingEnsUsernames = self.controller.getMyPendingEnsUsernames()
|
||||
for dto in pendingEnsUsernames:
|
||||
let item = Item(chainId: dto.chainId,
|
||||
ensUsername: dto.username,
|
||||
let item = Item(chainId: dto.chainId,
|
||||
ensUsername: dto.username,
|
||||
isPending: true)
|
||||
self.view.model().addItem(item)
|
||||
|
||||
|
@ -167,11 +167,11 @@ proc setPubKey*(self: Module, password: string) =
|
|||
var success: bool
|
||||
if(not responseObj.getProp("success", success)):
|
||||
info "remote call is not executed with success", methodName="setPubKey"
|
||||
|
||||
|
||||
var respResult: string
|
||||
if(responseObj.getProp("result", respResult)):
|
||||
let item = Item(chainId: self.tmpSendEnsTransactionDetails.chainId,
|
||||
ensUsername: self.tmpSendEnsTransactionDetails.ensUsername,
|
||||
let item = Item(chainId: self.tmpSendEnsTransactionDetails.chainId,
|
||||
ensUsername: self.tmpSendEnsTransactionDetails.ensUsername,
|
||||
isPending: true)
|
||||
self.view.model().addItem(item)
|
||||
self.view.emitTransactionWasSentSignal(response)
|
||||
|
@ -205,7 +205,7 @@ proc onEnsUsernameRemoved(self: Module, chainId: int, ensUsername: string) =
|
|||
self.controller.fixPreferredName(true)
|
||||
self.view.model().removeItemByEnsUsername(chainId, ensUsername)
|
||||
|
||||
method removeEnsUsername*(self: Module, chainId: int, ensUsername: string): bool =
|
||||
method removeEnsUsername*(self: Module, chainId: int, ensUsername: string): bool =
|
||||
if (not self.controller.removeEnsUsername(chainId, ensUsername)):
|
||||
info "an error occurred removing ens username", methodName="removeEnsUsername", ensUsername, chainId
|
||||
return false
|
||||
|
@ -313,7 +313,7 @@ method authenticateAndRegisterEns*(self: Module, chainId: int, ensUsername: stri
|
|||
## if acc.isNil:
|
||||
## echo "error: selected account to send a transaction from is not known"
|
||||
## return
|
||||
## let keyPair = self.controller.getKeycardByKeyUid(acc.keyUid)
|
||||
## let keyPair = self.controller.getKeycardsWithSameKeyUid(acc.keyUid)
|
||||
## if keyPair.len == 0:
|
||||
## self.controller.authenticateUser()
|
||||
## else:
|
||||
|
@ -356,7 +356,7 @@ method getWalletDefaultAddress*(self: Module): string =
|
|||
method getCurrentCurrency*(self: Module): string =
|
||||
return self.controller.getCurrentCurrency()
|
||||
|
||||
method getFiatValue*(self: Module, cryptoBalance: string, cryptoSymbol: string, fiatSymbol: string): string =
|
||||
method getFiatValue*(self: Module, cryptoBalance: string, cryptoSymbol: string, fiatSymbol: string): string =
|
||||
var floatCryptoBalance: float = 0
|
||||
try:
|
||||
floatCryptoBalance = parseFloat(cryptoBalance)
|
||||
|
|
|
@ -44,62 +44,70 @@ proc init*(self: Controller) =
|
|||
return
|
||||
self.delegate.onDisplayKeycardSharedModuleFlow()
|
||||
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
let args = KeypairArgs(e)
|
||||
self.delegate.onKeypairSynced(args.keypair)
|
||||
|
||||
self.events.on(SIGNAL_LOGGEDIN_USER_IMAGE_CHANGED) do(e: Args):
|
||||
self.delegate.onLoggedInUserImageChanged()
|
||||
|
||||
self.events.on(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.delegate.onNewKeycardSet(args.keycard)
|
||||
|
||||
self.events.on(SIGNAL_KEYPAIR_CHANGED) do(e: Args):
|
||||
let args = KeypairArgs(e)
|
||||
self.delegate.resolveRelatedKeycardsForKeypair(args.keypair)
|
||||
self.delegate.onKeycardChange(args.keycard)
|
||||
|
||||
self.events.on(SIGNAL_KEYCARD_LOCKED) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.delegate.onKeycardLocked(args.keycard.keyUid, args.keycard.keycardUid)
|
||||
|
||||
self.events.on(SIGNAL_KEYCARD_UNLOCKED) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.delegate.onKeycardUnlocked(args.keycard.keyUid, args.keycard.keycardUid)
|
||||
|
||||
self.events.on(SIGNAL_KEYCARD_NAME_CHANGED) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.delegate.onKeycardNameChanged(args.keycard.keycardUid, args.keycard.keycardName)
|
||||
|
||||
self.events.on(SIGNAL_KEYCARD_UID_UPDATED) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.delegate.onKeycardUidUpdated(args.oldKeycardUid, args.keycard.keycardUid)
|
||||
|
||||
self.events.on(SIGNAL_KEYCARD_ACCOUNTS_REMOVED) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.delegate.onKeycardAccountsRemoved(args.keycard.keyUid, args.keycard.keycardUid, args.keycard.accountsAddresses)
|
||||
self.delegate.onKeycardChange(args.keycard)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e: Args):
|
||||
let args = AccountArgs(e)
|
||||
self.delegate.onWalletAccountUpdated(args.account)
|
||||
self.delegate.onWalletAccountChange(args.account)
|
||||
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
# self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e: Args):
|
||||
# self.delegate.rebuildKeycardsList()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED) do(e: Args):
|
||||
let args = AccountArgs(e)
|
||||
self.delegate.onWalletAccountChange(args.account)
|
||||
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
# self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e: Args):
|
||||
# self.delegate.rebuildKeycardsList()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e: Args):
|
||||
let args = AccountArgs(e)
|
||||
self.delegate.onWalletAccountChange(args.account)
|
||||
|
||||
proc getAllKnownKeycardsGroupedByKeyUid*(self: Controller): seq[KeycardDto] =
|
||||
return self.walletAccountService.getAllKnownKeycardsGroupedByKeyUid()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e: Args):
|
||||
let args = AccountArgs(e)
|
||||
self.delegate.onWalletAccountChange(args.account)
|
||||
|
||||
proc getAllKnownKeycards*(self: Controller): seq[KeycardDto] =
|
||||
return self.walletAccountService.getAllKnownKeycards()
|
||||
proc getKeycardsWithSameKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardsWithSameKeyUid(keyUid)
|
||||
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
# proc getKeypairs*(self: Controller): seq[wallet_account_service.KeypairDto] =
|
||||
# return self.walletAccountService.getKeypairs()
|
||||
proc getKeypairs*(self: Controller): seq[wallet_account_service.KeypairDto] =
|
||||
return self.walletAccountService.getKeypairs()
|
||||
|
||||
proc getKeypairByKeyUid*(self: Controller, keyUid: string): wallet_account_service.KeypairDto =
|
||||
return self.walletAccountService.getKeypairByKeyUid(keyUid)
|
|
@ -65,10 +65,13 @@ method runCreateNewPairingCodePopup*(self: AccessInterface, keyUid: string) {.ba
|
|||
method onLoggedInUserImageChanged*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method resolveRelatedKeycardsForKeypair*(self: AccessInterface, keypair: KeypairDto) {.base.} =
|
||||
method onKeypairSynced*(self: AccessInterface, keypair: KeypairDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onNewKeycardSet*(self: AccessInterface, keyPair: KeycardDto) {.base.} =
|
||||
method onKeycardChange*(self: AccessInterface, keycard: KeycardDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onWalletAccountChange*(self: AccessInterface, account: WalletAccountDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onKeycardLocked*(self: AccessInterface, keyUid: string, keycardUid: string) {.base.} =
|
||||
|
@ -83,12 +86,6 @@ method onKeycardNameChanged*(self: AccessInterface, keycardUid: string, keycardN
|
|||
method onKeycardUidUpdated*(self: AccessInterface, keycardUid: string, keycardNewUid: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onKeycardAccountsRemoved*(self: AccessInterface, keyUid: string, keycardUid: string, accountsToRemove: seq[string]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onWalletAccountUpdated*(self: AccessInterface, account: WalletAccountDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method prepareKeycardDetailsModel*(self: AccessInterface, keyUid: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -23,11 +23,6 @@ export io_interface
|
|||
logScope:
|
||||
topics = "profile-section-profile-module"
|
||||
|
||||
type
|
||||
BuildItemReason {.pure.} = enum
|
||||
MainView
|
||||
DetailsView
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
|
@ -197,32 +192,65 @@ proc findAccountByAccountAddress(accounts: seq[WalletAccountDto], address: strin
|
|||
return acc
|
||||
return nil
|
||||
|
||||
proc buildKeycardItem(self: Module, keypair: KeypairDto, keycard: KeycardDto, reason: BuildItemReason):
|
||||
KeycardItem =
|
||||
proc addAccountsToKeycardItem(self: Module, item: KeycardItem, accounts: seq[WalletAccountDto]) =
|
||||
if accounts.len == 0:
|
||||
return
|
||||
var accType = accounts[0].walletType
|
||||
if accType == WalletTypeGenerated:
|
||||
item.setPairType(KeyPairType.Profile.int)
|
||||
item.setPubKey(singletonInstance.userProfile.getPubKey())
|
||||
item.setImage(singletonInstance.userProfile.getIcon())
|
||||
if accType == WalletTypeSeed:
|
||||
item.setPairType(KeyPairType.SeedImport.int)
|
||||
item.setIcon("keycard")
|
||||
if accType == WalletTypeKey:
|
||||
item.setPairType(KeyPairType.PrivateKeyImport.int)
|
||||
item.setIcon("keycard")
|
||||
for acc in accounts:
|
||||
if acc.isChat:
|
||||
continue
|
||||
var icon = ""
|
||||
if acc.emoji.len == 0:
|
||||
icon = "wallet"
|
||||
item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId,
|
||||
icon = icon, balance = 0.0))
|
||||
|
||||
proc buildMainViewKeycardItem(self: Module, keypair: KeypairDto): KeycardItem =
|
||||
if keypair.isNil or keypair.keycards.len == 0:
|
||||
return
|
||||
var item = initKeycardItem(keycardUid = "",
|
||||
keyUid = keypair.keyUid,
|
||||
pubKey = "",
|
||||
locked = false,
|
||||
name = keypair.name)
|
||||
## If all created keycards for certain keypair are locked, then we need to display that item as locked.
|
||||
item.setLocked(keypair.keycards.all(kp => kp.keycardLocked))
|
||||
self.addAccountsToKeycardItem(item, keypair.accounts)
|
||||
return item
|
||||
|
||||
proc buildDetailsViewKeycardItem(self: Module, keycard: KeycardDto): KeycardItem =
|
||||
let isAccountInKnownAccounts = proc(knownAccounts: seq[WalletAccountDto], address: string): bool =
|
||||
for i in 0 ..< knownAccounts.len:
|
||||
if cmpIgnoreCase(knownAccounts[i].address, address) == 0:
|
||||
return true
|
||||
return false
|
||||
|
||||
if keycard.keyUid.len == 0:
|
||||
return
|
||||
let keypair = self.controller.getKeypairByKeyUid(keycard.keyUid)
|
||||
if keypair.isNil:
|
||||
return
|
||||
|
||||
var knownAccounts: seq[WalletAccountDto]
|
||||
var unknownAccountsAddresses: seq[string]
|
||||
for accAddr in keycard.accountsAddresses:
|
||||
let account = findAccountByAccountAddress(keypair.accounts, accAddr)
|
||||
if account.isNil:
|
||||
## We are here if the keycard is not sync yet with the app's state. That may happen if there are more copies of the
|
||||
## We are here if the keycard is not synced yet with the app's state. That may happen if there are more copies of the
|
||||
## same keycard, then deleting an account for a keypair syncs the inserted keycard, but other copies of the card
|
||||
## remain with that account till the moment they are synced.
|
||||
unknownAccountsAddresses.add(accAddr)
|
||||
continue
|
||||
if reason == BuildItemReason.MainView and
|
||||
isAccountInKnownAccounts(knownAccounts, accAddr):
|
||||
# if there are more then one keycard for a single keypair we don't want to add the same keypair more than once
|
||||
# that's why caller of this proc should set `upgradeItem` to true, if item with the same `keyUid` was already added
|
||||
# to a model for the `MainView`
|
||||
continue
|
||||
knownAccounts.add(account)
|
||||
var item = initKeycardItem(keycardUid = keycard.keycardUid,
|
||||
keyUid = keycard.keyUid,
|
||||
|
@ -230,52 +258,29 @@ proc buildKeycardItem(self: Module, keypair: KeypairDto, keycard: KeycardDto, re
|
|||
locked = keycard.keycardLocked,
|
||||
name = keycard.keycardName)
|
||||
if knownAccounts.len == 0:
|
||||
if reason == BuildItemReason.MainView:
|
||||
return nil
|
||||
item.setPairType(KeyPairType.SeedImport.int)
|
||||
item.setIcon("keycard")
|
||||
else:
|
||||
item.setDerivedFrom(keypair.derivedFrom)
|
||||
|
||||
for ka in knownAccounts:
|
||||
var icon = ""
|
||||
if ka.walletType == WalletTypeDefaultStatusAccount:
|
||||
item.setPairType(KeyPairType.Profile.int)
|
||||
item.setPubKey(singletonInstance.userProfile.getPubKey())
|
||||
item.setImage(singletonInstance.userProfile.getIcon())
|
||||
icon = "wallet"
|
||||
if ka.walletType == WalletTypeSeed:
|
||||
item.setPairType(KeyPairType.SeedImport.int)
|
||||
item.setIcon("keycard")
|
||||
if ka.walletType == WalletTypeKey:
|
||||
item.setPairType(KeyPairType.PrivateKeyImport.int)
|
||||
item.setIcon("keycard")
|
||||
item.addAccount(newKeyPairAccountItem(ka.name, ka.path, ka.address, ka.publicKey, ka.emoji, ka.colorId, icon = icon, balance = 0.0))
|
||||
if reason == BuildItemReason.DetailsView:
|
||||
var i = 0
|
||||
for ua in unknownAccountsAddresses:
|
||||
i.inc
|
||||
let name = atc.KEYCARD_ACCOUNT_NAME_OF_UNKNOWN_WALLET_ACCOUNT & $i
|
||||
item.addAccount(newKeyPairAccountItem(name, path = "", ua, pubKey = "", emoji = "", colorId = "", icon = "wallet", balance = 0.0))
|
||||
return item
|
||||
# add known accounts
|
||||
self.addAccountsToKeycardItem(item, knownAccounts)
|
||||
|
||||
proc areAllKnownKeycardsLockedForKeypair(self: Module, keyUid: string): bool =
|
||||
let allKnownKeycards = self.controller.getAllKnownKeycards()
|
||||
let keyUidRelatedKeycards = allKnownKeycards.filter(kp => kp.keyUid == keyUid)
|
||||
if keyUidRelatedKeycards.len == 0:
|
||||
return false
|
||||
return keyUidRelatedKeycards.all(kp => kp.keycardLocked)
|
||||
# add unknown accounts
|
||||
var i = 0
|
||||
for ua in unknownAccountsAddresses:
|
||||
i.inc
|
||||
let name = atc.KEYCARD_ACCOUNT_NAME_OF_UNKNOWN_WALLET_ACCOUNT & $i
|
||||
item.addAccount(newKeyPairAccountItem(name, path = "", ua, pubKey = "", emoji = "", colorId = "undefined", icon = "wallet", balance = 0.0))
|
||||
return item
|
||||
|
||||
proc buildKeycardList(self: Module) =
|
||||
var items: seq[KeycardItem]
|
||||
let migratedKeyPairs = self.controller.getAllKnownKeycardsGroupedByKeyUid()
|
||||
for kp in migratedKeyPairs:
|
||||
let keypair = self.controller.getKeypairByKeyUid(kp.keyUid)
|
||||
let item = self.buildKeycardItem(keypair, kp, BuildItemReason.MainView)
|
||||
let keypairs = self.controller.getKeypairs()
|
||||
for kp in keypairs:
|
||||
let item = self.buildMainViewKeycardItem(kp)
|
||||
if item.isNil:
|
||||
continue
|
||||
## 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)
|
||||
if items.len > 0:
|
||||
self.view.setKeycardItems(items)
|
||||
|
@ -286,46 +291,32 @@ method onLoggedInUserImageChanged*(self: Module) =
|
|||
return
|
||||
self.view.keycardDetailsModel().setImage(singletonInstance.userProfile.getPubKey(), singletonInstance.userProfile.getIcon())
|
||||
|
||||
method resolveRelatedKeycardsForKeypair*(self: Module, keypair: KeypairDto) =
|
||||
method resolveRelatedKeycardsForKeypair(self: Module, keypair: KeypairDto) =
|
||||
if keypair.keyUid.len == 0:
|
||||
error "cannot rebuild keycards for a keypair with empty keyUid"
|
||||
return
|
||||
var
|
||||
mainViewItem: KeycardItem
|
||||
detailsViewItems: seq[KeycardItem]
|
||||
|
||||
let
|
||||
appHasDisplayedKeycards = not self.view.keycardModel().getItemForKeyUid(keypair.keyUid).isNil
|
||||
thereAreDisplayedKeycardsForKeypair = not self.view.keycardModel().getItemForKeyUid(keypair.keyUid).isNil
|
||||
detailsViewCurrentlyDisplayed = not self.view.keycardDetailsModel().isNil
|
||||
|
||||
# create main view item
|
||||
let mainViewItem = self.buildMainViewKeycardItem(keypair)
|
||||
|
||||
# prepare main view item and if needed details view item
|
||||
var detailsViewItems: seq[KeycardItem]
|
||||
for kc in keypair.keycards:
|
||||
# create main view item
|
||||
if mainViewItem.isNil:
|
||||
mainViewItem = self.buildKeycardItem(keypair, kc, BuildItemReason.MainView)
|
||||
else:
|
||||
for accAddr in kc.accountsAddresses:
|
||||
if mainViewItem.containsAccountAddress(accAddr):
|
||||
continue
|
||||
let account = findAccountByAccountAddress(keypair.accounts, accAddr)
|
||||
if account.isNil:
|
||||
## we should never be here cause all accounts are firstly added to wallet
|
||||
continue
|
||||
mainViewItem.addAccount(newKeyPairAccountItem(account.name, account.path, account.address, account.publicKey,
|
||||
account.emoji, account.colorId, icon = "", balance = 0.0))
|
||||
let item = self.buildDetailsViewKeycardItem(kc)
|
||||
if not item.isNil:
|
||||
detailsViewItems.add(item)
|
||||
|
||||
# create details view item if model is not nil (means the details view is currently active)
|
||||
if detailsViewCurrentlyDisplayed:
|
||||
let item = self.buildKeycardItem(keypair, kc, BuildItemReason.DetailsView)
|
||||
if not item.isNil:
|
||||
detailsViewItems.add(item)
|
||||
|
||||
if appHasDisplayedKeycards:
|
||||
if thereAreDisplayedKeycardsForKeypair:
|
||||
if keypair.keycards.len == 0:
|
||||
# remove all related keycards from the app
|
||||
self.view.keycardModel().removeItemWithKeyUid(keypair.keyUid)
|
||||
self.view.keycardModel().removeItemsWithKeyUid(keypair.keyUid)
|
||||
if not detailsViewCurrentlyDisplayed:
|
||||
return
|
||||
self.view.keycardDetailsModel().removeItemWithKeyUid(keypair.keyUid)
|
||||
self.view.keycardDetailsModel().removeItemsWithKeyUid(keypair.keyUid)
|
||||
return
|
||||
if keypair.keycards.len > 0:
|
||||
# replace displayed keycards
|
||||
|
@ -343,100 +334,65 @@ method resolveRelatedKeycardsForKeypair*(self: Module, keypair: KeypairDto) =
|
|||
return
|
||||
self.view.keycardDetailsModel().setItems(detailsViewItems)
|
||||
|
||||
method onNewKeycardSet*(self: Module, keyPair: KeycardDto) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# let keypairs = self.controller.getKeypairs()
|
||||
# var mainViewItem = self.view.keycardModel().getItemForKeyUid(keyPair.keyUid)
|
||||
# if mainViewItem.isNil:
|
||||
# mainViewItem = self.buildKeycardItem(keypairs, keyPair, BuildItemReason.MainView)
|
||||
# if not mainViewItem.isNil:
|
||||
# self.view.keycardModel().addItem(mainViewItem)
|
||||
# else:
|
||||
# for accAddr in keyPair.accountsAddresses:
|
||||
# if mainViewItem.containsAccountAddress(accAddr):
|
||||
# continue
|
||||
# let account = findAccountByAccountAddress(keypairs, accAddr)
|
||||
# if account.isNil:
|
||||
# ## we should never be here cause all keypairs are firstly added to wallet
|
||||
# continue
|
||||
# mainViewItem.addAccount(newKeyPairAccountItem(account.name, account.path, account.address, account.publicKey,
|
||||
# account.emoji, account.colorId, icon = "", balance = 0.0))
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# var detailsViewItem = self.view.keycardDetailsModel().getItemForKeycardUid(keyPair.keycardUid)
|
||||
# if detailsViewItem.isNil:
|
||||
# detailsViewItem = self.buildKeycardItem(keypairs, keyPair, BuildItemReason.DetailsView)
|
||||
# if not detailsViewItem.isNil:
|
||||
# self.view.keycardDetailsModel().addItem(detailsViewItem)
|
||||
# else:
|
||||
# for accAddr in keyPair.accountsAddresses:
|
||||
# if detailsViewItem.containsAccountAddress(accAddr):
|
||||
# continue
|
||||
# let account = findAccountByAccountAddress(keypairs, accAddr)
|
||||
# if account.isNil:
|
||||
# ## we should never be here cause all keypairs are firstly added to wallet
|
||||
# continue
|
||||
# detailsViewItem.addAccount(newKeyPairAccountItem(account.name, account.path, account.address, account.publicKey,
|
||||
# account.emoji, account.colorId, icon = "", balance = 0.0))
|
||||
method onKeypairSynced*(self: Module, keypair: KeypairDto) =
|
||||
self.resolveRelatedKeycardsForKeypair(keypair)
|
||||
|
||||
method onKeycardChange*(self: Module, keycard: KeycardDto) =
|
||||
assert keycard.keyUid.len > 0, "cannot proceed with keycard with an empty keyUid"
|
||||
let keypair = self.controller.getKeypairByKeyUid(keycard.keyUid)
|
||||
if keypair.isNil:
|
||||
return
|
||||
self.resolveRelatedKeycardsForKeypair(keypair)
|
||||
|
||||
method onWalletAccountChange*(self: Module, account: WalletAccountDto) =
|
||||
if account.isNil or account.keyUid.len == 0:
|
||||
return
|
||||
let keypair = self.controller.getKeypairByKeyUid(account.keyUid)
|
||||
if not keypair.isNil:
|
||||
self.resolveRelatedKeycardsForKeypair(keypair)
|
||||
return
|
||||
# we should be here if the last account for a keypair was deleted
|
||||
if self.view.keycardModel().getItemForKeyUid(account.keyUid).isNil:
|
||||
return
|
||||
self.view.keycardModel().removeItemsWithKeyUid(account.keyUid)
|
||||
if self.view.keycardDetailsModel().isNil:
|
||||
return
|
||||
self.view.keycardDetailsModel().removeItemsWithKeyUid(account.keyUid)
|
||||
|
||||
method onKeycardLocked*(self: Module, keyUid: string, keycardUid: string) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# self.view.keycardModel().setLockedForKeycardsWithKeyUid(keyUid, true)
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# self.view.keycardDetailsModel().setLockedForKeycardWithKeycardUid(keycardUid, true)
|
||||
assert keyUid.len > 0, "cannot proceed with keycard with an empty keyUid"
|
||||
assert keycardUid.len > 0, "cannot proceed with keycard with an empty keycardUid"
|
||||
let keypair = self.controller.getKeypairByKeyUid(keyUid)
|
||||
if keypair.isNil:
|
||||
return
|
||||
if keypair.keycards.all(kp => kp.keycardLocked):
|
||||
self.view.keycardModel().setLockedForKeycardsWithKeyUid(keyUid, true)
|
||||
if self.view.keycardDetailsModel().isNil:
|
||||
return
|
||||
self.view.keycardDetailsModel().setLockedForKeycardWithKeycardUid(keycardUid, true)
|
||||
|
||||
method onKeycardUnlocked*(self: Module, keyUid: string, keycardUid: string) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# self.view.keycardModel().setLockedForKeycardsWithKeyUid(keyUid, false)
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# self.view.keycardDetailsModel().setLockedForKeycardWithKeycardUid(keycardUid, false)
|
||||
self.view.keycardModel().setLockedForKeycardsWithKeyUid(keyUid, false)
|
||||
if self.view.keycardDetailsModel().isNil:
|
||||
return
|
||||
self.view.keycardDetailsModel().setLockedForKeycardWithKeycardUid(keycardUid, false)
|
||||
|
||||
method onKeycardNameChanged*(self: Module, keycardUid: string, keycardNewName: string) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# self.view.keycardModel().setNameForKeycardWithKeycardUid(keycardUid, keycardNewName)
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# self.view.keycardDetailsModel().setNameForKeycardWithKeycardUid(keycardUid, keycardNewName)
|
||||
# keycard on the main view should always follow corresponding keypair
|
||||
if self.view.keycardDetailsModel().isNil:
|
||||
return
|
||||
self.view.keycardDetailsModel().setNameForKeycardWithKeycardUid(keycardUid, keycardNewName)
|
||||
|
||||
method onKeycardUidUpdated*(self: Module, keycardUid: string, keycardNewUid: string) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# self.view.keycardDetailsModel().setKeycardUid(keycardUid, keycardNewUid)
|
||||
|
||||
method onKeycardAccountsRemoved*(self: Module, keyUid: string, keycardUid: string, accountsToRemove: seq[string]) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# self.view.keycardModel().removeAccountsFromKeycardsWithKeyUid(keyUid, accountsToRemove, removeKeycardItemIfHasNoAccounts = true)
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# self.view.keycardDetailsModel().removeAccountsFromKeycardWithKeycardUid(keycardUid, accountsToRemove, removeKeycardItemIfHasNoAccounts = true)
|
||||
|
||||
method onWalletAccountUpdated*(self: Module, account: WalletAccountDto) =
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
discard
|
||||
# self.view.keycardModel().updateDetailsForAddressForKeyPairsWithKeyUid(account.keyUid, account.address, account.name,
|
||||
# account.colorId, account.emoji)
|
||||
# if self.view.keycardDetailsModel().isNil:
|
||||
# return
|
||||
# self.view.keycardDetailsModel().updateDetailsForAddressForKeyPairsWithKeyUid(account.keyUid, account.address, account.name,
|
||||
# account.colorId, account.emoji)
|
||||
if self.view.keycardDetailsModel().isNil:
|
||||
return
|
||||
self.view.keycardDetailsModel().setKeycardUid(keycardUid, keycardNewUid)
|
||||
|
||||
method prepareKeycardDetailsModel*(self: Module, keyUid: string) =
|
||||
let keypair = self.controller.getKeypairByKeyUid(keyUid)
|
||||
var items: seq[KeycardItem]
|
||||
let allKnownKeycards = self.controller.getAllKnownKeycards()
|
||||
for kp in allKnownKeycards:
|
||||
if kp.keyUid != keyUid:
|
||||
continue
|
||||
let item = self.buildKeycardItem(keypair, kp, BuildItemReason.DetailsView)
|
||||
let keycards = self.controller.getKeycardsWithSameKeyUid(keyUid)
|
||||
for kc in keycards:
|
||||
let item = self.buildDetailsViewKeycardItem(kc)
|
||||
if item.isNil:
|
||||
continue
|
||||
items.add(item)
|
||||
|
|
|
@ -34,8 +34,8 @@ proc updateAccountPosition*(self: Controller, address: string, position: int) =
|
|||
proc deleteAccount*(self: Controller, address: string) =
|
||||
self.walletAccountService.deleteAccount(address)
|
||||
|
||||
proc getKeycardByKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardByKeyUid(keyUid)
|
||||
proc getKeycardsWithSameKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardsWithSameKeyUid(keyUid)
|
||||
|
||||
proc isKeycardAccount*(self: Controller, account: WalletAccountDto): bool =
|
||||
return self.walletAccountService.isKeycardAccount(account)
|
||||
|
@ -46,9 +46,6 @@ proc getWalletAccount*(self: Controller, address: string): WalletAccountDto =
|
|||
proc getKeypairs*(self: Controller): seq[KeypairDto] =
|
||||
return self.walletAccountService.getKeypairs()
|
||||
|
||||
proc getAllKnownKeycardsGroupedByKeyUid*(self: Controller): seq[KeycardDto] =
|
||||
return self.walletAccountService.getAllKnownKeycardsGroupedByKeyUid()
|
||||
|
||||
proc toggleIncludeWatchOnlyAccount*(self: Controller) =
|
||||
self.walletAccountService.toggleIncludeWatchOnlyAccount()
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ QtObject:
|
|||
self.endResetModel()
|
||||
self.countChanged()
|
||||
|
||||
proc onUpdatedAccount*(self: Model, account: Item) =
|
||||
proc onUpdatedAccount*(self: Model, account: Item) =
|
||||
var i = 0
|
||||
for item in self.items.mitems:
|
||||
if account.address == item.address:
|
||||
|
|
|
@ -60,8 +60,8 @@ method convertWalletAccountDtoToKeyPairAccountItem(self: Module, account: Wallet
|
|||
balanceFetched = false)
|
||||
|
||||
method createKeypairItems*(self: Module, walletAccounts: seq[WalletAccountDto]): seq[KeyPairItem] =
|
||||
var keyPairItems = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(),
|
||||
excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = false)
|
||||
var keyPairItems = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,
|
||||
excludePrivateKeyKeypairs = false)
|
||||
|
||||
var item = newKeyPairItem()
|
||||
item.setIcon("show")
|
||||
|
@ -82,6 +82,9 @@ method refreshWalletAccounts*(self: Module) =
|
|||
self.view.setItems(items)
|
||||
|
||||
method load*(self: Module) =
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
self.refreshWalletAccounts()
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e:Args):
|
||||
self.refreshWalletAccounts()
|
||||
|
||||
|
@ -94,7 +97,7 @@ method load*(self: Module) =
|
|||
self.view.onUpdatedAccount(walletAccountToWalletSettingsAccountsItem(args.account, keycardAccount))
|
||||
|
||||
self.events.on(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.refreshWalletAccounts()
|
||||
|
|
|
@ -96,7 +96,7 @@ method authenticateAndBuy*(self: Module, packId: string, address: string, gas: s
|
|||
## if acc.isNil:
|
||||
## echo "error: selected account to send a transaction from is not known"
|
||||
## return
|
||||
## let keyPair = self.controller.getKeycardByKeyUid(acc.keyUid)
|
||||
## let keyPair = self.controller.getKeycardsWithSameKeyUid(acc.keyUid)
|
||||
## if keyPair.len == 0:
|
||||
## self.controller.authenticateUser()
|
||||
## else:
|
||||
|
|
|
@ -50,8 +50,8 @@ proc getCurrentCurrency*(self: Controller): string =
|
|||
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
|
||||
return self.currencyService.getCurrencyFormat(symbol)
|
||||
|
||||
proc getKeycardByKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardByKeyUid(keyUid)
|
||||
proc getKeycardsWithSameKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardsWithSameKeyUid(keyUid)
|
||||
|
||||
proc getWalletAccount*(self: Controller, address: string): WalletAccountDto =
|
||||
return self.walletAccountService.getAccountByAddress(address)
|
||||
|
|
|
@ -168,6 +168,13 @@ method setFillterAllAddresses*(self: Module) =
|
|||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("walletSection", newQVariant(self.view))
|
||||
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
let args = KeypairArgs(e)
|
||||
self.setTotalCurrencyBalance()
|
||||
for acc in args.keypair.accounts:
|
||||
if acc.removed:
|
||||
self.filter.removeAddress(acc.address)
|
||||
self.notifyFilterChanged()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e:Args):
|
||||
self.notifyFilterChanged()
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e:Args):
|
||||
|
@ -192,7 +199,7 @@ method load*(self: Module) =
|
|||
self.setTotalCurrencyBalance()
|
||||
self.notifyFilterChanged()
|
||||
self.events.on(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.notifyFilterChanged()
|
||||
|
|
|
@ -58,10 +58,10 @@ proc init*(self: Controller) =
|
|||
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||
return self.walletAccountService.getWalletAccounts()
|
||||
|
||||
proc getChainIds*(self: Controller): seq[int] =
|
||||
proc getChainIds*(self: Controller): seq[int] =
|
||||
return self.networkService.getNetworks().map(n => n.chainId)
|
||||
|
||||
proc getEnabledChainIds*(self: Controller): seq[int] =
|
||||
proc getEnabledChainIds*(self: Controller): seq[int] =
|
||||
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
|
||||
|
||||
proc getCurrentCurrency*(self: Controller): string =
|
||||
|
@ -70,8 +70,8 @@ proc getCurrentCurrency*(self: Controller): string =
|
|||
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
|
||||
return self.currencyService.getCurrencyFormat(symbol)
|
||||
|
||||
proc getKeycardByKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardByKeyUid(keyUid)
|
||||
proc getKeycardsWithSameKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
return self.walletAccountService.getKeycardsWithSameKeyUid(keyUid)
|
||||
|
||||
proc getAccountByAddress*(self: Controller, address: string): WalletAccountDto =
|
||||
return self.walletAccountService.getAccountByAddress(address)
|
||||
|
@ -87,7 +87,7 @@ proc authenticateUser*(self: Controller, keyUid = "") =
|
|||
keyUid: keyUid)
|
||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
||||
|
||||
proc getEstimatedTime*(self: Controller, chainId: int, maxFeePerGas: string): EstimatedTime =
|
||||
proc getEstimatedTime*(self: Controller, chainId: int, maxFeePerGas: string): EstimatedTime =
|
||||
return self.transactionService.getEstimatedTime(chainId, maxFeePerGas)
|
||||
|
||||
proc suggestedRoutes*(self: Controller, account: string, amount: Uint256, token: string, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[uint64], sendType: int, lockedInAmounts: string): string =
|
||||
|
@ -98,6 +98,6 @@ proc transfer*(self: Controller, from_addr: string, to_addr: string, tokenSymbol
|
|||
value: string, uuid: string, selectedRoutes: string, password: string) =
|
||||
self.transactionService.transfer(from_addr, to_addr, tokenSymbol, value, uuid, selectedRoutes, password)
|
||||
|
||||
proc suggestedFees*(self: Controller, chainId: int): string =
|
||||
proc suggestedFees*(self: Controller, chainId: int): string =
|
||||
let suggestedFees = self.transactionService.suggestedFees(chainId)
|
||||
return suggestedFees.toJson()
|
||||
|
|
|
@ -85,6 +85,9 @@ method load*(self: Module) =
|
|||
singletonInstance.engine.setRootContextProperty("walletSectionSend", newQVariant(self.view))
|
||||
|
||||
# these connections should be part of the controller's init method
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
self.refreshWalletAccounts()
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_SAVED) do(e:Args):
|
||||
self.refreshWalletAccounts()
|
||||
|
||||
|
@ -104,7 +107,7 @@ method load*(self: Module) =
|
|||
self.refreshWalletAccounts()
|
||||
|
||||
self.events.on(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
if not args.success:
|
||||
return
|
||||
self.refreshWalletAccounts()
|
||||
|
@ -152,7 +155,7 @@ method authenticateAndTransfer*(
|
|||
## if acc.isNil:
|
||||
## echo "error: selected account to send a transaction from is not known"
|
||||
## return
|
||||
## let keyPair = self.controller.getKeycardByKeyUid(acc.keyUid)
|
||||
## let keyPair = self.controller.getKeycardsWithSameKeyUid(acc.keyUid)
|
||||
## if keyPair.len == 0:
|
||||
## self.controller.authenticateUser()
|
||||
## else:
|
||||
|
|
|
@ -10,14 +10,8 @@ export keypair_item
|
|||
logScope:
|
||||
topics = "shared-keypairs"
|
||||
|
||||
proc buildKeyPairsList*(keypairs: seq[KeypairDto], allMigratedKeypairs: seq[KeycardDto],
|
||||
excludeAlreadyMigratedPairs: bool, excludePrivateKeyKeypairs: bool): seq[KeyPairItem] =
|
||||
let keyPairMigrated = proc(keyUid: string): bool =
|
||||
result = false
|
||||
for kp in allMigratedKeypairs:
|
||||
if kp.keyUid == keyUid:
|
||||
return true
|
||||
|
||||
proc buildKeyPairsList*(keypairs: seq[KeypairDto], excludeAlreadyMigratedPairs: bool,
|
||||
excludePrivateKeyKeypairs: bool): seq[KeyPairItem] =
|
||||
var items: seq[KeyPairItem]
|
||||
for kp in keypairs:
|
||||
if kp.accounts.len == 0:
|
||||
|
@ -25,7 +19,7 @@ proc buildKeyPairsList*(keypairs: seq[KeypairDto], allMigratedKeypairs: seq[Keyc
|
|||
error "there must not be any keypair without accounts", keyUid=kp.keyUid
|
||||
return
|
||||
let publicKey = kp.accounts[0].publicKey # in case of other but the profile keypair we take public key of first account as keypair's public key
|
||||
let kpMigrated = keyPairMigrated(kp.keyUid)
|
||||
let kpMigrated = kp.keycards.len > 0
|
||||
if excludeAlreadyMigratedPairs and kpMigrated:
|
||||
continue
|
||||
if kp.keypairType == KeypairTypeProfile:
|
||||
|
@ -54,7 +48,7 @@ proc buildKeyPairsList*(keypairs: seq[KeypairDto], allMigratedKeypairs: seq[Keyc
|
|||
locked = false,
|
||||
name = kp.name,
|
||||
image = "",
|
||||
icon = if keyPairMigrated(kp.keyUid): "keycard" else: "key_pair_seed_phrase",
|
||||
icon = if kpMigrated: "keycard" else: "key_pair_seed_phrase",
|
||||
pairType = KeyPairType.SeedImport,
|
||||
derivedFrom = kp.derivedFrom,
|
||||
lastUsedDerivationIndex = kp.lastUsedDerivationIndex,
|
||||
|
@ -74,7 +68,7 @@ proc buildKeyPairsList*(keypairs: seq[KeypairDto], allMigratedKeypairs: seq[Keyc
|
|||
locked = false,
|
||||
name = kp.name,
|
||||
image = "",
|
||||
icon = if keyPairMigrated(kp.keyUid): "keycard" else: "objects",
|
||||
icon = if kpMigrated: "keycard" else: "objects",
|
||||
pairType = KeyPairType.PrivateKeyImport,
|
||||
derivedFrom = kp.derivedFrom,
|
||||
lastUsedDerivationIndex = kp.lastUsedDerivationIndex,
|
||||
|
|
|
@ -14,7 +14,7 @@ type
|
|||
QtObject:
|
||||
type KeyPairItem* = ref object of QObject
|
||||
keyUid: string
|
||||
pubKey: string
|
||||
pubKey: string
|
||||
locked: bool
|
||||
name: string
|
||||
image: string
|
||||
|
|
|
@ -123,9 +123,6 @@ proc getKeypairs*(self: Controller): seq[KeypairDto] =
|
|||
proc getKeypairByKeyUid*(self: Controller, keyUid: string): KeypairDto =
|
||||
return self.walletAccountService.getKeypairByKeyUid(keyUid)
|
||||
|
||||
proc getAllKnownKeycardsGroupedByKeyUid*(self: Controller): seq[KeycardDto] =
|
||||
return self.walletAccountService.getAllKnownKeycardsGroupedByKeyUid()
|
||||
|
||||
proc finalizeAction*(self: Controller) =
|
||||
self.delegate.finalizeAction()
|
||||
|
||||
|
@ -147,7 +144,7 @@ proc fetchDetailsForAddresses*(self: Controller, addresses: seq[string]) =
|
|||
self.uniqueFetchingDetailsId = $now().toTime().toUnix()
|
||||
self.walletAccountService.fetchDetailsForAddresses(self.uniqueFetchingDetailsId, addresses)
|
||||
|
||||
proc addWalletAccount*(self: Controller, createKeystoreFile, doPasswordHashing: bool, name, address, path, publicKey,
|
||||
proc addWalletAccount*(self: Controller, createKeystoreFile, doPasswordHashing: bool, name, address, path, publicKey,
|
||||
keyUid, accountType, colorId, emoji: string): bool =
|
||||
var password: string
|
||||
if createKeystoreFile:
|
||||
|
@ -155,33 +152,33 @@ proc addWalletAccount*(self: Controller, createKeystoreFile, doPasswordHashing:
|
|||
if password.len == 0:
|
||||
info "cannot create keystore file if provided password is empty", name=name, address=address
|
||||
return false
|
||||
let err = self.walletAccountService.addWalletAccount(password, doPasswordHashing, name, address, path, publicKey,
|
||||
let err = self.walletAccountService.addWalletAccount(password, doPasswordHashing, name, address, path, publicKey,
|
||||
keyUid, accountType, colorId, emoji)
|
||||
if err.len > 0:
|
||||
info "adding wallet account failed", name=name, address=address
|
||||
return false
|
||||
return true
|
||||
|
||||
proc addNewPrivateKeyKeypair*(self: Controller, privateKey: string, doPasswordHashing: bool, keyUid, keypairName,
|
||||
proc addNewPrivateKeyKeypair*(self: Controller, privateKey: string, doPasswordHashing: bool, keyUid, keypairName,
|
||||
rootWalletMasterKey: string, account: WalletAccountDto): bool =
|
||||
let password = self.getPassword() # password must not be empty in this context
|
||||
if password.len == 0:
|
||||
info "cannot create keystore file if provided password is empty", keypairName=keypairName, keyUid=keyUid
|
||||
return false
|
||||
let err = self.walletAccountService.addNewPrivateKeyKeypair(privateKey, password, doPasswordHashing, keyUid,
|
||||
let err = self.walletAccountService.addNewPrivateKeyKeypair(privateKey, password, doPasswordHashing, keyUid,
|
||||
keyPairName, rootWalletMasterKey, account)
|
||||
if err.len > 0:
|
||||
info "adding new keypair from private key failed", keypairName=keypairName, keyUid=keyUid
|
||||
return false
|
||||
return true
|
||||
|
||||
proc addNewSeedPhraseKeypair*(self: Controller, seedPhrase: string, doPasswordHashing: bool, keyUid, keypairName,
|
||||
proc addNewSeedPhraseKeypair*(self: Controller, seedPhrase: string, doPasswordHashing: bool, keyUid, keypairName,
|
||||
rootWalletMasterKey: string, accounts: seq[WalletAccountDto]): bool =
|
||||
let password = self.getPassword() # password must not be empty in this context
|
||||
if password.len == 0:
|
||||
info "cannot create keystore file if provided password is empty", keypairName=keypairName, keyUid=keyUid
|
||||
return false
|
||||
let err = self.walletAccountService.addNewSeedPhraseKeypair(seedPhrase, password, doPasswordHashing, keyUid,
|
||||
let err = self.walletAccountService.addNewSeedPhraseKeypair(seedPhrase, password, doPasswordHashing, keyUid,
|
||||
keypairName, rootWalletMasterKey, accounts)
|
||||
if err.len > 0:
|
||||
info "adding new keypair from seed phrase failed", keypairName=keypairName, keyUid=keyUid
|
||||
|
@ -221,14 +218,14 @@ proc disconnectKeycardReponseSignal(self: Controller) =
|
|||
|
||||
proc connectKeycardReponseSignal(self: Controller) =
|
||||
self.connectionKeycardResponse = self.events.onWithUUID(SIGNAL_KEYCARD_RESPONSE) do(e: Args):
|
||||
let args = KeycardArgs(e)
|
||||
let args = KeycardLibArgs(e)
|
||||
self.disconnectKeycardReponseSignal()
|
||||
self.delegate.onDerivedAddressesFromKeycardFetched(args.flowType, args.flowEvent, self.tmpPaths)
|
||||
|
||||
proc cancelCurrentFlow*(self: Controller) =
|
||||
self.keycardService.cancelCurrentFlow()
|
||||
# in most cases we're running another flow after canceling the current one,
|
||||
# this way we're giving to the keycard some time to cancel the current flow
|
||||
# in most cases we're running another flow after canceling the current one,
|
||||
# this way we're giving to the keycard some time to cancel the current flow
|
||||
sleep(200)
|
||||
|
||||
proc fetchAddressesFromKeycard*(self: Controller, bip44Paths: seq[string]) =
|
||||
|
|
|
@ -65,11 +65,11 @@ proc newModule*[T](delegate: T,
|
|||
result.events = events
|
||||
result.walletAccountService = walletAccountService
|
||||
result.view = newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController(result, events, accountsService, walletAccountService, keycardService)
|
||||
result.authenticationReason = AuthenticationReason.AddingAccount
|
||||
result.fetchingAddressesIsInProgress = false
|
||||
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
|
@ -80,8 +80,8 @@ method loadForAddingAccount*[T](self: Module[T], addingWatchOnlyAccount: bool) =
|
|||
self.view.setEditMode(false)
|
||||
self.view.setCurrentState(newMainState(nil))
|
||||
|
||||
var items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(),
|
||||
excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = true)
|
||||
var items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,
|
||||
excludePrivateKeyKeypairs = true)
|
||||
if items.len == 0:
|
||||
error "list of identified keypairs is empty, but it must have at least a profile keypair"
|
||||
return
|
||||
|
@ -112,10 +112,10 @@ method loadForEditingAccount*[T](self: Module[T], address: string) =
|
|||
self.view.setCurrentState(newMainState(nil))
|
||||
|
||||
let accountDto = self.controller.getWalletAccount(address)
|
||||
var addressDetailsItem = newDerivedAddressItem(order = 0,
|
||||
address = accountDto.address,
|
||||
var addressDetailsItem = newDerivedAddressItem(order = 0,
|
||||
address = accountDto.address,
|
||||
publicKey = accountDto.publicKey,
|
||||
path = accountDto.path,
|
||||
path = accountDto.path,
|
||||
alreadyCreated = true,
|
||||
hasActivity = false,
|
||||
loaded = true)
|
||||
|
@ -124,7 +124,7 @@ method loadForEditingAccount*[T](self: Module[T], address: string) =
|
|||
self.view.setStoredAccountName(accountDto.name)
|
||||
self.view.setStoredSelectedColorId(accountDto.colorId)
|
||||
self.view.setStoredSelectedEmoji(accountDto.emoji)
|
||||
self.view.setAccountName(accountDto.name)
|
||||
self.view.setAccountName(accountDto.name)
|
||||
self.view.setSelectedColorId(accountDto.colorId)
|
||||
self.view.setSelectedEmoji(accountDto.emoji)
|
||||
|
||||
|
@ -135,8 +135,8 @@ method loadForEditingAccount*[T](self: Module[T], address: string) =
|
|||
self.view.setSelectedOrigin(item)
|
||||
self.view.setWatchOnlyAccAddress(addressDetailsItem)
|
||||
else:
|
||||
var items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(),
|
||||
excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = false)
|
||||
var items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,
|
||||
excludePrivateKeyKeypairs = false)
|
||||
if items.len == 0:
|
||||
error "list of identified keypairs is empty, but it must have at least a profile keypair"
|
||||
return
|
||||
|
@ -146,7 +146,7 @@ method loadForEditingAccount*[T](self: Module[T], address: string) =
|
|||
if item.containsAccountAddress(address):
|
||||
selectedOrigin = item
|
||||
break
|
||||
|
||||
|
||||
if selectedOrigin.isNil or selectedOrigin.getKeyUid().len == 0:
|
||||
error "selected address for editing is not known among identified keypairs", address=address
|
||||
return
|
||||
|
@ -161,13 +161,13 @@ method loadForEditingAccount*[T](self: Module[T], address: string) =
|
|||
self.view.setDerivationPath(accountDto.path)
|
||||
self.view.setSelectedOrigin(selectedOrigin)
|
||||
|
||||
self.delegate.onAddAccountModuleLoaded()
|
||||
self.delegate.onAddAccountModuleLoaded()
|
||||
|
||||
proc tryKeycardSync[T](self: Module[T]) =
|
||||
proc tryKeycardSync[T](self: Module[T]) =
|
||||
if self.controller.getPin().len == 0:
|
||||
return
|
||||
let dataForKeycardToSync = SharedKeycarModuleArgs(
|
||||
pin: self.controller.getPin(),
|
||||
pin: self.controller.getPin(),
|
||||
keyUid: self.controller.getAuthenticatedKeyUid()
|
||||
)
|
||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC, dataForKeycardToSync)
|
||||
|
@ -203,7 +203,7 @@ method onCancelActionClicked*[T](self: Module[T]) =
|
|||
return
|
||||
debug "waa_cancel_action", currState=currStateObj.stateType()
|
||||
currStateObj.executeCancelCommand(self.controller)
|
||||
|
||||
|
||||
method onPrimaryActionClicked*[T](self: Module[T]) =
|
||||
let currStateObj = self.view.currentStateObj()
|
||||
if currStateObj.isNil:
|
||||
|
@ -365,7 +365,7 @@ proc resolveSuggestedPathForSelectedOrigin[T](self: Module[T]): tuple[suggestedP
|
|||
return (suggestedPath, nextIndex)
|
||||
nextIndex = selectedOrigin.getLastUsedDerivationIndex() + 1
|
||||
for i in nextIndex ..< self.getNumOfAddressesToGenerate():
|
||||
let suggestedPath = account_constants.PATH_WALLET_ROOT & "/" & $i
|
||||
let suggestedPath = account_constants.PATH_WALLET_ROOT & "/" & $i
|
||||
if keypair.accounts.filter(x => x.path == suggestedPath).len == 0:
|
||||
return (suggestedPath, i)
|
||||
error "we couldn't find available path for new account"
|
||||
|
@ -449,7 +449,7 @@ method validSeedPhrase*[T](self: Module[T], seedPhrase: string): bool =
|
|||
|
||||
proc setDerivedAddresses[T](self: Module[T], derivedAddresses: seq[DerivedAddressDto]) =
|
||||
defer: self.fetchingAddressesIsInProgress = false
|
||||
|
||||
|
||||
var items: seq[DerivedAddressItem]
|
||||
let derivationPath = self.view.getDerivationPath()
|
||||
if derivationPath.endsWith("/"):
|
||||
|
@ -468,7 +468,7 @@ proc setDerivedAddresses[T](self: Module[T], derivedAddresses: seq[DerivedAddres
|
|||
self.view.derivedAddressModel().setItems(items)
|
||||
if items.len == 0:
|
||||
info "couldn't resolve an address for the set path"
|
||||
return
|
||||
return
|
||||
self.changeSelectedDerivedAddress(items[0].getAddress())
|
||||
|
||||
method onDerivedAddressesFetched*[T](self: Module[T], derivedAddresses: seq[DerivedAddressDto], error: string) =
|
||||
|
@ -543,13 +543,13 @@ method onAddressDetailsFetched*[T](self: Module[T], derivedAddresses: seq[Derive
|
|||
if currStateObj.isNil:
|
||||
error "waa_cannot resolve current state"
|
||||
return
|
||||
|
||||
|
||||
# we always receive responses one by one
|
||||
if derivedAddresses.len == 1:
|
||||
var addressDetailsItem = newDerivedAddressItem(order = 0,
|
||||
address = derivedAddresses[0].address,
|
||||
publicKey = derivedAddresses[0].publicKey,
|
||||
path = derivedAddresses[0].path,
|
||||
var addressDetailsItem = newDerivedAddressItem(order = 0,
|
||||
address = derivedAddresses[0].address,
|
||||
publicKey = derivedAddresses[0].publicKey,
|
||||
path = derivedAddresses[0].path,
|
||||
alreadyCreated = derivedAddresses[0].alreadyCreated,
|
||||
hasActivity = derivedAddresses[0].hasActivity,
|
||||
loaded = true)
|
||||
|
@ -585,7 +585,7 @@ method authenticateForEditingDerivationPath*[T](self: Module[T]) =
|
|||
|
||||
proc doAddAccount[T](self: Module[T]) =
|
||||
self.view.setDisablePopup(true)
|
||||
let
|
||||
let
|
||||
selectedOrigin = self.view.getSelectedOrigin()
|
||||
selectedAddrItem = self.view.getSelectedDerivedAddress()
|
||||
var
|
||||
|
@ -631,17 +631,17 @@ proc doAddAccount[T](self: Module[T]) =
|
|||
success = self.controller.addNewPrivateKeyKeypair(
|
||||
privateKey = self.controller.getGeneratedAccount().privateKey,
|
||||
doPasswordHashing = not singletonInstance.userProfile.getIsKeycardUser(),
|
||||
keyUid = keyUid,
|
||||
keypairName = keypairName,
|
||||
keyUid = keyUid,
|
||||
keypairName = keypairName,
|
||||
rootWalletMasterKey = rootWalletMasterKey,
|
||||
account = WalletAccountDto(
|
||||
address: address,
|
||||
keyUid: keyUid,
|
||||
publicKey: publicKey,
|
||||
walletType: accountType,
|
||||
path: path,
|
||||
walletType: accountType,
|
||||
path: path,
|
||||
name: self.view.getAccountName(),
|
||||
colorId: self.view.getSelectedColorId(),
|
||||
colorId: self.view.getSelectedColorId(),
|
||||
emoji: self.view.getSelectedEmoji()
|
||||
)
|
||||
)
|
||||
|
@ -651,17 +651,17 @@ proc doAddAccount[T](self: Module[T]) =
|
|||
success = self.controller.addNewSeedPhraseKeypair(
|
||||
seedPhrase = self.controller.getSeedPhrase(),
|
||||
doPasswordHashing = not singletonInstance.userProfile.getIsKeycardUser(),
|
||||
keyUid = keyUid,
|
||||
keypairName = keypairName,
|
||||
keyUid = keyUid,
|
||||
keypairName = keypairName,
|
||||
rootWalletMasterKey = rootWalletMasterKey,
|
||||
accounts = @[WalletAccountDto(
|
||||
address: address,
|
||||
keyUid: keyUid,
|
||||
publicKey: publicKey,
|
||||
walletType: accountType,
|
||||
path: path,
|
||||
walletType: accountType,
|
||||
path: path,
|
||||
name: self.view.getAccountName(),
|
||||
colorId: self.view.getSelectedColorId(),
|
||||
colorId: self.view.getSelectedColorId(),
|
||||
emoji: self.view.getSelectedEmoji()
|
||||
)]
|
||||
)
|
||||
|
@ -671,23 +671,23 @@ proc doAddAccount[T](self: Module[T]) =
|
|||
success = self.controller.addWalletAccount(
|
||||
createKeystoreFile = createKeystoreFile,
|
||||
doPasswordHashing = doPasswordHashing,
|
||||
name = self.view.getAccountName(),
|
||||
address = address,
|
||||
name = self.view.getAccountName(),
|
||||
address = address,
|
||||
path = path,
|
||||
publicKey = publicKey,
|
||||
keyUid = keyUid,
|
||||
accountType = accountType,
|
||||
publicKey = publicKey,
|
||||
keyUid = keyUid,
|
||||
accountType = accountType,
|
||||
colorId = self.view.getSelectedColorId(),
|
||||
emoji = self.view.getSelectedEmoji())
|
||||
if not success:
|
||||
error "failed to store account", address=selectedAddrItem.getAddress()
|
||||
|
||||
|
||||
self.closeAddAccountPopup()
|
||||
|
||||
proc doEditAccount[T](self: Module[T]) =
|
||||
self.view.setDisablePopup(true)
|
||||
let selectedOrigin = self.view.getSelectedOrigin()
|
||||
|
||||
|
||||
var address = self.view.getWatchOnlyAccAddress().getAddress()
|
||||
if selectedOrigin.getPairType() == KeyPairType.Profile.int or
|
||||
selectedOrigin.getPairType() == KeyPairType.SeedImport.int:
|
||||
|
@ -696,7 +696,7 @@ proc doEditAccount[T](self: Module[T]) =
|
|||
elif selectedOrigin.getPairType() == KeyPairType.PrivateKeyImport.int:
|
||||
let selectedAddrItem = self.view.getPrivateKeyAccAddress()
|
||||
address = selectedAddrItem.getAddress()
|
||||
|
||||
|
||||
if self.controller.updateAccount(
|
||||
address = address,
|
||||
accountName = self.view.getAccountName(),
|
||||
|
|
|
@ -130,7 +130,7 @@ proc disconnectKeycardReponseSignal(self: Controller) =
|
|||
|
||||
proc connectKeycardReponseSignal(self: Controller) =
|
||||
self.connectionKeycardResponse = self.events.onWithUUID(SIGNAL_KEYCARD_RESPONSE) do(e: Args):
|
||||
let args = KeycardArgs(e)
|
||||
let args = KeycardLibArgs(e)
|
||||
self.delegate.onKeycardResponse(args.flowType, args.flowEvent)
|
||||
|
||||
proc disconnectKeycardSyncSignal(self: Controller) =
|
||||
|
@ -179,7 +179,7 @@ proc init*(self: Controller, fullConnect = true) =
|
|||
|
||||
if fullConnect:
|
||||
handlerId = self.events.onWithUUID(SIGNAL_NEW_KEYCARD_SET) do(e: Args):
|
||||
let args = KeycardActivityArgs(e)
|
||||
let args = KeycardArgs(e)
|
||||
self.tmpAddingMigratedKeypairSuccess = args.success
|
||||
self.delegate.onSecondaryActionClicked()
|
||||
self.connectionIds.add(handlerId)
|
||||
|
@ -662,15 +662,10 @@ proc removeMigratedAccountsForKeycard*(self: Controller, keyUid: string, keycard
|
|||
proc getAddingMigratedKeypairSuccess*(self: Controller): bool =
|
||||
return self.tmpAddingMigratedKeypairSuccess
|
||||
|
||||
proc getKeycardByKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
proc getKeycardsWithSameKeyUid*(self: Controller, keyUid: string): seq[KeycardDto] =
|
||||
if not serviceApplicable(self.walletAccountService):
|
||||
return
|
||||
return self.walletAccountService.getKeycardByKeyUid(keyUid)
|
||||
|
||||
proc getAllKnownKeycardsGroupedByKeyUid*(self: Controller): seq[KeycardDto] =
|
||||
if not serviceApplicable(self.walletAccountService):
|
||||
return
|
||||
return self.walletAccountService.getAllKnownKeycardsGroupedByKeyUid()
|
||||
return self.walletAccountService.getKeycardsWithSameKeyUid(keyUid)
|
||||
|
||||
proc getAllKnownKeycards*(self: Controller): seq[KeycardDto] =
|
||||
if not serviceApplicable(self.walletAccountService):
|
||||
|
|
|
@ -28,7 +28,7 @@ method executePrePrimaryStateCommand*(self: EnterSeedPhraseState, controller: Co
|
|||
if self.verifiedSeedPhrase:
|
||||
## should always be true, since it's not possible to do primary command otherwise (button is disabled on the UI)
|
||||
let keyUid = controller.getKeyUidForSeedPhrase(sp)
|
||||
self.keyPairAlreadyMigrated = controller.getKeycardByKeyUid(keyUid).len > 0
|
||||
self.keyPairAlreadyMigrated = controller.getKeycardsWithSameKeyUid(keyUid).len > 0
|
||||
if self.keyPairAlreadyMigrated:
|
||||
controller.prepareKeyPairForProcessing(keyUid)
|
||||
return
|
||||
|
@ -78,22 +78,22 @@ method executeCancelCommand*(self: EnterSeedPhraseState, controller: Controller)
|
|||
self.flowType == FlowType.CreateCopyOfAKeycard:
|
||||
controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
|
||||
|
||||
method resolveKeycardNextState*(self: EnterSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
method resolveKeycardNextState*(self: EnterSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
controller: Controller): State =
|
||||
let state = ensureReaderAndCardPresence(self, keycardFlowType, keycardEvent, controller)
|
||||
if not state.isNil:
|
||||
return state
|
||||
if self.flowType == FlowType.SetupNewKeycard:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.keyUid.len > 0:
|
||||
return createState(StateType.MigratingKeyPair, self.flowType, nil)
|
||||
if self.flowType == FlowType.SetupNewKeycardOldSeedPhrase:
|
||||
if keycardFlowType == ResponseTypeValueEnterNewPIN and
|
||||
if keycardFlowType == ResponseTypeValueEnterNewPIN and
|
||||
keycardEvent.error.len > 0 and
|
||||
keycardEvent.error == ErrorRequireInit:
|
||||
return createState(StateType.CreatePin, self.flowType, nil)
|
||||
if self.flowType == FlowType.CreateCopyOfAKeycard:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.keyUid.len > 0:
|
||||
controller.setDestinationKeycardUid(keycardEvent.instanceUID)
|
||||
return createState(StateType.CopyingKeycard, self.flowType, nil)
|
||||
|
|
|
@ -68,8 +68,8 @@ QtObject:
|
|||
self.endRemoveRows()
|
||||
self.countChanged()
|
||||
|
||||
proc removeItemWithKeyUid*(self: KeycardModel, keyUid: string) =
|
||||
for i in 0 ..< self.items.len:
|
||||
proc removeItemsWithKeyUid*(self: KeycardModel, keyUid: string) =
|
||||
for i in countdown(self.items.len-1, 0):
|
||||
if self.items[i].getKeyUid() == keyUid:
|
||||
self.removeItem(i)
|
||||
|
||||
|
|
|
@ -394,8 +394,8 @@ method onKeycardResponse*[T](self: Module[T], keycardFlowType: string, keycardEv
|
|||
|
||||
proc prepareKeyPairItemForAuthentication[T](self: Module[T], keyUid: string) =
|
||||
var item = newKeyPairItem()
|
||||
let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(),
|
||||
excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = false)
|
||||
let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,
|
||||
excludePrivateKeyKeypairs = false)
|
||||
for it in items:
|
||||
if it.getKeyUid() == keyUid:
|
||||
item = it
|
||||
|
@ -416,8 +416,8 @@ method setKeyPairForProcessing*[T](self: Module[T], item: KeyPairItem) =
|
|||
|
||||
method prepareKeyPairForProcessing*[T](self: Module[T], keyUid: string, keycardUid = "") =
|
||||
var item = newKeyPairItem()
|
||||
let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(),
|
||||
excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = false)
|
||||
let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,
|
||||
excludePrivateKeyKeypairs = false)
|
||||
for it in items:
|
||||
if it.getKeyUid() == keyUid:
|
||||
item = it
|
||||
|
@ -447,8 +447,8 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Paths
|
|||
self.controller.runGetMetadataFlow(resolveAddress = true)
|
||||
return
|
||||
if flowToRun == FlowType.SetupNewKeycard:
|
||||
let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(),
|
||||
excludeAlreadyMigratedPairs = true, excludePrivateKeyKeypairs = false)
|
||||
let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = true,
|
||||
excludePrivateKeyKeypairs = false)
|
||||
self.view.createKeyPairModel(items)
|
||||
self.view.setCurrentState(newSelectExistingKeyPairState(flowToRun, nil))
|
||||
self.controller.readyToDisplayPopup()
|
||||
|
@ -535,19 +535,6 @@ method setSelectedKeyPair*[T](self: Module[T], item: KeyPairItem) =
|
|||
paths, keycardDto)
|
||||
self.setKeyPairForProcessing(item)
|
||||
|
||||
proc updateKeyPairItemIfDataAreKnown[T](self: Module[T], address: string, item: var KeyPairItem): bool =
|
||||
let accounts = self.controller.getWalletAccounts()
|
||||
for a in accounts:
|
||||
if a.isChat or a.walletType == WalletTypeWatch or cmpIgnoreCase(a.address, address) != 0:
|
||||
continue
|
||||
var icon = ""
|
||||
if a.walletType == WalletTypeDefaultStatusAccount:
|
||||
icon = "wallet"
|
||||
item.setKeyUid(a.keyUid)
|
||||
item.addAccount(newKeyPairAccountItem(a.name, a.path, a.address, a.publicKey, a.emoji, a.colorId, icon, balance = 0.0, balanceFetched = true))
|
||||
return true
|
||||
return false
|
||||
|
||||
method onTokensRebuilt*[T](self: Module[T], accountsTokens: OrderedTable[string, seq[WalletTokenDto]]) =
|
||||
if self.getKeyPairForProcessing().isNil:
|
||||
return
|
||||
|
@ -570,16 +557,32 @@ proc buildKeyPairItemBasedOnCardMetadata[T](self: Module[T], cardMetadata: CardM
|
|||
result.item.setKeyUid(currKp.getKeyUid())
|
||||
result.item.setPubKey(currKp.getPubKey())
|
||||
result.knownKeyPair = true
|
||||
var unknonwAccountNumber = 0
|
||||
for wa in cardMetadata.walletAccounts:
|
||||
if self.updateKeyPairItemIfDataAreKnown(wa.address, result.item):
|
||||
continue
|
||||
let (balance, balanceFetched) = self.controller.getOrFetchBalanceForAddressInPreferredCurrency(wa.address)
|
||||
result.knownKeyPair = false
|
||||
unknonwAccountNumber.inc
|
||||
let name = atc.KEYCARD_ACCOUNT_NAME_OF_UNKNOWN_WALLET_ACCOUNT & $unknonwAccountNumber
|
||||
result.item.addAccount(newKeyPairAccountItem(name, wa.path, wa.address, pubKey = wa.publicKey, emoji = "",
|
||||
colorId = "", icon = "undefined", balance, balanceFetched))
|
||||
# resolve known accounts first
|
||||
let accounts = self.controller.getWalletAccounts()
|
||||
for acc in accounts:
|
||||
for cardAcc in cardMetadata.walletAccounts:
|
||||
if acc.isChat or acc.walletType == WalletTypeWatch or cmpIgnoreCase(acc.address, cardAcc.address) != 0:
|
||||
continue
|
||||
var icon = ""
|
||||
if acc.emoji.len == 0:
|
||||
icon = "wallet"
|
||||
result.item.addAccount(newKeyPairAccountItem(acc.name, acc.path, acc.address, acc.publicKey, acc.emoji, acc.colorId, icon,
|
||||
balance = 0.0, balanceFetched = true))
|
||||
# handle unknown accounts
|
||||
var unknownAccountNumber = 0
|
||||
for cardAcc in cardMetadata.walletAccounts:
|
||||
var found = false
|
||||
for acc in accounts:
|
||||
if cmpIgnoreCase(acc.address, cardAcc.address) == 0:
|
||||
found = true
|
||||
break
|
||||
if not found:
|
||||
let (balance, balanceFetched) = self.controller.getOrFetchBalanceForAddressInPreferredCurrency(cardAcc.address)
|
||||
result.knownKeyPair = false
|
||||
unknownAccountNumber.inc
|
||||
let name = atc.KEYCARD_ACCOUNT_NAME_OF_UNKNOWN_WALLET_ACCOUNT & $unknownAccountNumber
|
||||
result.item.addAccount(newKeyPairAccountItem(name, cardAcc.path, cardAcc.address, pubKey = cardAcc.publicKey,
|
||||
emoji = "", colorId = "undefined", icon = "wallet", balance, balanceFetched))
|
||||
|
||||
method updateKeyPairForProcessing*[T](self: Module[T], cardMetadata: CardMetadata) =
|
||||
let(item, knownKeyPair) = self.buildKeyPairItemBasedOnCardMetadata(cardMetadata)
|
||||
|
|
|
@ -149,7 +149,7 @@ proc init*(self: Controller) =
|
|||
self.connectionIds.add(handlerId)
|
||||
|
||||
handlerId = self.events.onWithUUID(SIGNAL_KEYCARD_RESPONSE) do(e: Args):
|
||||
let args = KeycardArgs(e)
|
||||
let args = KeycardLibArgs(e)
|
||||
self.delegate.onKeycardResponse(args.flowType, args.flowEvent)
|
||||
self.connectionIds.add(handlerId)
|
||||
|
||||
|
|
|
@ -189,6 +189,12 @@ QtObject:
|
|||
of "wallet-tick-reload":
|
||||
self.refetchAllOwnedCollectibles()
|
||||
|
||||
self.events.on(SIGNAL_KEYPAIR_SYNCED) do(e: Args):
|
||||
let args = KeypairArgs(e)
|
||||
for acc in args.keypair.accounts:
|
||||
if acc.removed:
|
||||
self.removeAddress(acc.address)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_DELETED) do(e:Args):
|
||||
self.removeAddress(AccountArgs(e).account.address)
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ include internal
|
|||
include ../../common/async_tasks
|
||||
|
||||
type
|
||||
KeycardArgs* = ref object of Args
|
||||
KeycardLibArgs* = ref object of Args
|
||||
flowType*: string
|
||||
flowEvent*: KeycardEvent
|
||||
|
||||
|
@ -97,14 +97,14 @@ QtObject:
|
|||
debug "keycard_signal", response=signal
|
||||
|
||||
var typeObj, eventObj: JsonNode
|
||||
if(not jsonSignal.getProp(ResponseKeyType, typeObj) or
|
||||
if(not jsonSignal.getProp(ResponseKeyType, typeObj) or
|
||||
not jsonSignal.getProp(ResponseKeyEvent, eventObj)):
|
||||
return
|
||||
|
||||
|
||||
let flowType = typeObj.getStr
|
||||
let flowEvent = toKeycardEvent(eventObj)
|
||||
self.lastReceivedKeycardData = (flowType: flowType, flowEvent: flowEvent)
|
||||
self.events.emit(SIGNAL_KEYCARD_RESPONSE, KeycardArgs(flowType: flowType, flowEvent: flowEvent))
|
||||
self.events.emit(SIGNAL_KEYCARD_RESPONSE, KeycardLibArgs(flowType: flowType, flowEvent: flowEvent))
|
||||
|
||||
proc receiveKeycardSignal(self: Service, signal: string) {.slot.} =
|
||||
self.processSignal(signal)
|
||||
|
@ -172,7 +172,7 @@ QtObject:
|
|||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc startLoadAccountFlow*(self: Service, seedPhraseLength: int, seedPhrase: string, pin: string, puk: string,
|
||||
proc startLoadAccountFlow*(self: Service, seedPhraseLength: int, seedPhrase: string, pin: string, puk: string,
|
||||
factoryReset: bool) =
|
||||
var payload = %* { }
|
||||
if seedPhrase.len > 0 and seedPhraseLength > 0:
|
||||
|
@ -196,7 +196,7 @@ QtObject:
|
|||
self.startFlow(payload)
|
||||
|
||||
proc startLoginFlowAutomatically*(self: Service, pin: string) =
|
||||
let payload = %* {
|
||||
let payload = %* {
|
||||
RequestParamPIN: pin
|
||||
}
|
||||
self.currentFlow = KCSFlowType.Login
|
||||
|
@ -213,7 +213,7 @@ QtObject:
|
|||
if factoryReset:
|
||||
payload[RequestParamFactoryReset] = %* factoryReset
|
||||
self.currentFlow = KCSFlowType.RecoverAccount
|
||||
self.startFlow(payload)
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startGetAppInfoFlow*(self: Service, factoryReset: bool) =
|
||||
var payload = %* { }
|
||||
|
@ -255,7 +255,7 @@ QtObject:
|
|||
error "in order to export private address path must not be outside of eip1581 tree"
|
||||
return
|
||||
|
||||
var payload = %* {
|
||||
var payload = %* {
|
||||
RequestParamBIP44Path: DefaultBIP44Path,
|
||||
RequestParamExportMasterAddress: exportMasterAddr,
|
||||
RequestParamExportPrivate: exportPrivateAddr
|
||||
|
@ -277,7 +277,7 @@ QtObject:
|
|||
error "one of paths in the list refers to a private address path which is not in eip1581 tree"
|
||||
return
|
||||
|
||||
var payload = %* {
|
||||
var payload = %* {
|
||||
RequestParamBIP44Path: DefaultBIP44Path,
|
||||
RequestParamExportMasterAddress: exportMasterAddr,
|
||||
RequestParamExportPrivate: exportPrivateAddr
|
||||
|
@ -293,7 +293,7 @@ QtObject:
|
|||
var name = cardName
|
||||
if cardName.len > CardNameLength:
|
||||
name = cardName[0 .. CardNameLength - 1]
|
||||
let payload = %* {
|
||||
let payload = %* {
|
||||
RequestParamPIN: pin,
|
||||
RequestParamCardName: name,
|
||||
RequestParamWalletPaths: walletPaths
|
||||
|
@ -302,7 +302,7 @@ QtObject:
|
|||
self.startFlow(payload)
|
||||
|
||||
proc startSignFlow*(self: Service, bip44Path: string, txHash: string) =
|
||||
var payload = %* {
|
||||
var payload = %* {
|
||||
RequestParamTXHash: EmptyTxHash,
|
||||
RequestParamBIP44Path: DefaultBIP44Path
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ type CurrentUserStatus* = object
|
|||
type
|
||||
SettingsFieldDto* = object
|
||||
name*: string
|
||||
value*: string
|
||||
value*: JsonNode
|
||||
|
||||
type
|
||||
SettingsDto* = object # There is no point to keep all these info as settings, but we must follow status-go response
|
||||
|
@ -156,10 +156,8 @@ proc toCurrentUserStatus*(jsonObj: JsonNode): CurrentUserStatus =
|
|||
discard jsonObj.getProp("text", result.text)
|
||||
|
||||
proc toSettingsFieldDto*(jsonObj: JsonNode): SettingsFieldDto =
|
||||
var field = SettingsFieldDto()
|
||||
field.name = jsonObj["name"].getStr()
|
||||
field.value = jsonObj["value"].getStr()
|
||||
result = field
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("value", result.value)
|
||||
|
||||
proc toSettingsDto*(jsonObj: JsonNode): SettingsDto =
|
||||
discard jsonObj.getProp(KEY_ADDRESS, result.address)
|
||||
|
|
|
@ -99,19 +99,19 @@ QtObject:
|
|||
if receivedData.settings.len > 0:
|
||||
for settingsField in receivedData.settings:
|
||||
if settingsField.name == KEY_CURRENCY:
|
||||
self.settings.currency = settingsField.value
|
||||
self.events.emit(SIGNAL_CURRENCY_UPDATED, SettingsTextValueArgs(value: settingsField.value))
|
||||
self.settings.currency = settingsField.value.getStr
|
||||
self.events.emit(SIGNAL_CURRENCY_UPDATED, SettingsTextValueArgs(value: self.settings.currency))
|
||||
if settingsField.name == KEY_DISPLAY_NAME:
|
||||
self.settings.displayName = settingsField.value
|
||||
self.events.emit(SIGNAL_DISPLAY_NAME_UPDATED, SettingsTextValueArgs(value: settingsField.value))
|
||||
self.settings.displayName = settingsField.value.getStr
|
||||
self.events.emit(SIGNAL_DISPLAY_NAME_UPDATED, SettingsTextValueArgs(value: self.settings.displayName))
|
||||
if settingsField.name == KEY_BIO:
|
||||
self.settings.bio = settingsField.value
|
||||
self.events.emit(SIGNAL_BIO_UPDATED, SettingsTextValueArgs(value: settingsField.value))
|
||||
self.settings.bio = settingsField.value.getStr
|
||||
self.events.emit(SIGNAL_BIO_UPDATED, SettingsTextValueArgs(value: self.settings.bio))
|
||||
if settingsField.name == KEY_MNEMONIC:
|
||||
self.settings.mnemonic = ""
|
||||
self.events.emit(SIGNAL_MNEMONIC_REMOVED, Args())
|
||||
if settingsField.name == INCLUDE_WATCH_ONLY_ACCOUNT:
|
||||
self.settings.includeWatchOnlyAccount = parseBool(settingsField.value)
|
||||
self.settings.includeWatchOnlyAccount = settingsField.value.getBool
|
||||
self.events.emit(SIGNAL_INCLUDE_WATCH_ONLY_ACCOUNTS_UPDATED, Args())
|
||||
|
||||
if receivedData.socialLinksInfo.links.len > 0 or
|
||||
|
|
|
@ -103,51 +103,55 @@ const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
|||
#################################################
|
||||
|
||||
type
|
||||
AddKeycardOrAddAccountsIfKeycardIsAddedTaskArg* = ref object of QObjectTaskArg
|
||||
SaveOrUpdateKeycardTaskArg* = ref object of QObjectTaskArg
|
||||
keycard: KeycardDto
|
||||
accountsComingFromKeycard: bool
|
||||
|
||||
const addKeycardOrAddAccountsIfKeycardIsAddedTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AddKeycardOrAddAccountsIfKeycardIsAddedTaskArg](argEncoded)
|
||||
const saveOrUpdateKeycardTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[SaveOrUpdateKeycardTaskArg](argEncoded)
|
||||
var responseJson = %*{
|
||||
"success": false,
|
||||
"keycard": arg.keycard.toJsonNode()
|
||||
}
|
||||
try:
|
||||
let response = backend.addKeycardOrAddAccountsIfKeycardIsAdded(
|
||||
arg.keycard.keycardUid,
|
||||
arg.keycard.keycardName,
|
||||
arg.keycard.keyUid,
|
||||
arg.keycard.accountsAddresses,
|
||||
let response = backend.saveOrUpdateKeycard(
|
||||
%* {
|
||||
"keycard-uid": arg.keycard.keycardUid,
|
||||
"keycard-name": arg.keycard.keycardName,
|
||||
# "keycard-locked" - no need to set it here, cause it will be set to false by the status-go
|
||||
"key-uid": arg.keycard.keyUid,
|
||||
"accounts-addresses": arg.keycard.accountsAddresses,
|
||||
# "position": - no need to set it here, cause it is fully maintained by the status-go
|
||||
},
|
||||
arg.accountsComingFromKeycard
|
||||
)
|
||||
let success = responseHasNoErrors("addKeycardOrAddAccountsIfKeycardIsAdded", response)
|
||||
let responseJson = %*{
|
||||
"success": success,
|
||||
"keycard": arg.keycard.toJsonNode()
|
||||
}
|
||||
arg.finish(responseJson)
|
||||
let success = responseHasNoErrors("saveOrUpdateKeycard", response)
|
||||
responseJson["success"] = %* success
|
||||
except Exception as e:
|
||||
error "error adding new keycard: ", message = e.msg
|
||||
arg.finish("")
|
||||
arg.finish(responseJson)
|
||||
|
||||
#################################################
|
||||
# Async remove migrated accounts for keycard
|
||||
#################################################
|
||||
|
||||
type
|
||||
RemoveMigratedAccountsForKeycardTaskArg* = ref object of QObjectTaskArg
|
||||
DeleteKeycardAccountsTaskArg* = ref object of QObjectTaskArg
|
||||
keycard: KeycardDto
|
||||
|
||||
const removeMigratedAccountsForKeycardTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[RemoveMigratedAccountsForKeycardTaskArg](argEncoded)
|
||||
const deleteKeycardAccountsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[DeleteKeycardAccountsTaskArg](argEncoded)
|
||||
var responseJson = %*{
|
||||
"success": false,
|
||||
"keycard": arg.keycard.toJsonNode()
|
||||
}
|
||||
try:
|
||||
let response = backend.removeMigratedAccountsForKeycard(
|
||||
let response = backend.deleteKeycardAccounts(
|
||||
arg.keycard.keycardUid,
|
||||
arg.keycard.accountsAddresses
|
||||
)
|
||||
let success = responseHasNoErrors("removeMigratedAccountsForKeycard", response)
|
||||
let responseJson = %*{
|
||||
"success": success,
|
||||
"keycard": arg.keycard.toJsonNode()
|
||||
}
|
||||
arg.finish(responseJson)
|
||||
let success = responseHasNoErrors("deleteKeycardAccounts", response)
|
||||
responseJson["success"] = %* success
|
||||
except Exception as e:
|
||||
error "error remove accounts from keycard: ", message = e.msg
|
||||
arg.finish("")
|
||||
arg.finish(responseJson)
|
|
@ -2,8 +2,7 @@ import tables, json, strformat, sequtils, sugar, strutils
|
|||
|
||||
include ../../common/json_utils
|
||||
|
||||
const WalletTypeDefaultStatusAccount* = ""
|
||||
const WalletTypeGenerated* = "generated"
|
||||
const WalletTypeGenerated* = "generated" # refers to accounts generated from the profile keypair
|
||||
const WalletTypeSeed* = "seed"
|
||||
const WalletTypeWatch* = "watch"
|
||||
const WalletTypeKey* = "key"
|
||||
|
@ -193,7 +192,7 @@ proc getBalance*(self: WalletTokenDto, chainIds: seq[int]): float64 =
|
|||
for chainId in chainIds:
|
||||
if self.balancesPerChain.hasKey(chainId):
|
||||
sum += self.balancesPerChain[chainId].balance
|
||||
|
||||
|
||||
return sum
|
||||
|
||||
proc getCurrencyBalance*(self: WalletTokenDto, chainIds: seq[int], currency: string): float64 =
|
||||
|
@ -202,14 +201,14 @@ proc getCurrencyBalance*(self: WalletTokenDto, chainIds: seq[int], currency: str
|
|||
for chainId in chainIds:
|
||||
if self.balancesPerChain.hasKey(chainId):
|
||||
sum += self.balancesPerChain[chainId].getCurrencyBalance(price)
|
||||
|
||||
|
||||
return sum
|
||||
|
||||
proc getVisibleForNetwork*(self: WalletTokenDto, chainIds: seq[int]): bool =
|
||||
for chainId in chainIds:
|
||||
if self.balancesPerChain.hasKey(chainId):
|
||||
return true
|
||||
|
||||
|
||||
return false
|
||||
|
||||
proc getVisibleForNetworkWithPositiveBalance*(self: WalletTokenDto, chainIds: seq[int]): bool =
|
||||
|
@ -219,7 +218,7 @@ proc getVisibleForNetworkWithPositiveBalance*(self: WalletTokenDto, chainIds: se
|
|||
|
||||
if self.balancesPerChain.hasKey(chainId) and self.balancesPerChain[chainId].balance > 0:
|
||||
return true
|
||||
|
||||
|
||||
return false
|
||||
|
||||
proc getCurrencyBalance*(self: WalletAccountDto, chainIds: seq[int], currency: string): float64 =
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import NimQml, Tables, json, sequtils, sugar, chronicles, strformat, stint, httpclient, net, strutils, os, times, algorithm
|
||||
import NimQml, Tables, json, sequtils, sugar, chronicles, strformat, stint, httpclient
|
||||
import net, strutils, os, times, algorithm, options
|
||||
import web3/ethtypes
|
||||
|
||||
import ../settings/service as settings_service
|
||||
|
@ -34,11 +35,10 @@ const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESSES_FETCHED* = "walletAccount/derivedA
|
|||
const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESSES_FROM_MNEMONIC_FETCHED* = "walletAccount/derivedAddressesFromMnemonicFetched"
|
||||
const SIGNAL_WALLET_ACCOUNT_ADDRESS_DETAILS_FETCHED* = "walletAccount/addressDetailsFetched"
|
||||
const SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED* = "walletAccount/positionUpdated"
|
||||
const SIGNAL_WALLET_ACCOUNT_OPERABILITY_UPDATED* = "walletAccount/operabilityUpdated"
|
||||
const SIGNAL_WALLET_ACCOUNT_OPERABILITY_UPDATED* = "walletAccount/operabilityUpdated" # TODO: will be used later, when we deal with account operability
|
||||
|
||||
const SIGNAL_KEYPAIR_CHANGED* = "keypairChanged"
|
||||
const SIGNAL_KEYPAIR_SYNCED* = "keypairSynced"
|
||||
const SIGNAL_KEYPAIR_NAME_CHANGED* = "keypairNameChanged"
|
||||
const SIGNAL_KEYPAIR_DELETED* = "keypairDeleted"
|
||||
const SIGNAL_NEW_KEYCARD_SET* = "newKeycardSet"
|
||||
const SIGNAL_KEYCARD_DELETED* = "keycardDeleted"
|
||||
const SIGNAL_KEYCARD_ACCOUNTS_REMOVED* = "keycardAccountsRemoved"
|
||||
|
@ -79,6 +79,11 @@ type AccountArgs* = ref object of Args
|
|||
type KeypairArgs* = ref object of Args
|
||||
keypair*: KeypairDto
|
||||
|
||||
type KeycardArgs* = ref object of Args
|
||||
success*: bool
|
||||
oldKeycardUid*: string
|
||||
keycard*: KeycardDto
|
||||
|
||||
type DerivedAddressesArgs* = ref object of Args
|
||||
uniqueId*: string
|
||||
derivedAddresses*: seq[DerivedAddressDto]
|
||||
|
@ -89,11 +94,6 @@ type TokensPerAccountArgs* = ref object of Args
|
|||
hasBalanceCache*: bool
|
||||
hasMarketValuesCache*: bool
|
||||
|
||||
type KeycardActivityArgs* = ref object of Args
|
||||
success*: bool
|
||||
oldKeycardUid*: string
|
||||
keycard*: KeycardDto
|
||||
|
||||
proc responseHasNoErrors(procName: string, response: RpcResponse[JsonNode]): bool =
|
||||
var errMsg = ""
|
||||
if not response.error.isNil:
|
||||
|
@ -123,8 +123,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 handleWalletAccount(self: Service, account: WalletAccountDto, notify: bool = true)
|
||||
proc handleKeypair(self: Service, keypair: KeypairDto)
|
||||
proc getAllKnownKeycards*(self: Service): seq[KeycardDto]
|
||||
proc removeMigratedAccountsForKeycard*(self: Service, keyUid: string, keycardUid: string, accountsToRemove: seq[string])
|
||||
|
@ -338,8 +337,6 @@ QtObject:
|
|||
if receivedData.keypairs.len > 0:
|
||||
for kp in receivedData.keypairs:
|
||||
self.handleKeypair(kp)
|
||||
## TODO: will be removed in the second part of synchronization improvements
|
||||
# self.handleKeycardActions(receivedData.keycardActions)
|
||||
|
||||
self.events.on(SignalType.Wallet.event) do(e:Args):
|
||||
var data = WalletSignal(e)
|
||||
|
@ -386,7 +383,7 @@ QtObject:
|
|||
error "error: ", errDescription
|
||||
return
|
||||
|
||||
proc addNewAccountToLocalStoreAndNotify(self: Service) =
|
||||
proc addNewAccountToLocalStoreAndNotify(self: Service, notify: bool = true) =
|
||||
let accounts = self.getAccounts()
|
||||
var newAccount: WalletAccountDto
|
||||
var found = false
|
||||
|
@ -406,18 +403,21 @@ QtObject:
|
|||
self.storeAccount(newAccount)
|
||||
|
||||
self.buildAllTokens(@[newAccount.address], store = true)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountArgs(account: newAccount))
|
||||
if notify:
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountArgs(account: newAccount))
|
||||
|
||||
proc removeAccountFromLocalStoreAndNotify(self: Service, address: string) =
|
||||
proc removeAccountFromLocalStoreAndNotify(self: Service, address: string, notify: bool = true) =
|
||||
if not self.walletAccountsContainsAddress(address):
|
||||
return
|
||||
let removedAcc = self.walletAccounts[address]
|
||||
self.walletAccounts.del(address)
|
||||
# updating related accounts for other accounts
|
||||
self.setRelatedAccountsForAllAccounts(removedAcc.keyUid)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountArgs(account: removedAcc))
|
||||
if notify:
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountArgs(account: removedAcc))
|
||||
|
||||
proc updateAccountInLocalStoreAndNotify(self: Service, address, name, colorId, emoji: string, position: int = -1, accOperability: string = "") =
|
||||
proc updateAccountInLocalStoreAndNotify(self: Service, address, name, colorId, emoji: string,
|
||||
position: Option[int] = none(int), notify: bool = true) =
|
||||
if not self.walletAccountsContainsAddress(address):
|
||||
return
|
||||
var account = self.getAccountByAddress(address)
|
||||
|
@ -429,15 +429,13 @@ QtObject:
|
|||
if emoji.len > 0 and emoji != account.emoji:
|
||||
account.emoji = emoji
|
||||
self.storeAccount(account, updateRelatedAccounts = false)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, AccountArgs(account: account))
|
||||
if position > -1 and position != account.position:
|
||||
account.position = position
|
||||
if notify:
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, AccountArgs(account: account))
|
||||
if position.isSome and position.get != account.position:
|
||||
account.position = position.get
|
||||
self.storeAccount(account, updateRelatedAccounts = false)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED, AccountArgs(account: account))
|
||||
if accOperability.len > 0 and account.operable != accOperability:
|
||||
account.operable = accOperability
|
||||
self.storeAccount(account, updateRelatedAccounts = false)
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_OPERABILITY_UPDATED, AccountArgs(account: account))
|
||||
if notify:
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_POSITION_UPDATED, AccountArgs(account: account))
|
||||
|
||||
## if password is not provided local keystore file won't be created
|
||||
proc addWalletAccount*(self: Service, password: string, doPasswordHashing: bool, name, address, path, publicKey,
|
||||
|
@ -573,7 +571,7 @@ QtObject:
|
|||
if not response.error.isNil:
|
||||
error "status-go error", procName="updateAccountPosition", errCode=response.error.code, errDesription=response.error.message
|
||||
return
|
||||
self.updateAccountInLocalStoreAndNotify(address, name = "", colorId = "", emoji = "", position)
|
||||
self.updateAccountInLocalStoreAndNotify(address, name = "", colorId = "", emoji = "", some(position))
|
||||
except Exception as e:
|
||||
error "error: ", procName="updateAccountPosition", errName=e.name, errDesription=e.msg
|
||||
|
||||
|
@ -749,8 +747,8 @@ QtObject:
|
|||
return 0.0
|
||||
|
||||
proc addKeycardOrAccountsAsync*(self: Service, keycard: KeycardDto, accountsComingFromKeycard: bool = false) =
|
||||
let arg = AddKeycardOrAddAccountsIfKeycardIsAddedTaskArg(
|
||||
tptr: cast[ByteAddress](addKeycardOrAddAccountsIfKeycardIsAddedTask),
|
||||
let arg = SaveOrUpdateKeycardTaskArg(
|
||||
tptr: cast[ByteAddress](saveOrUpdateKeycardTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onKeycardAdded",
|
||||
keycard: keycard,
|
||||
|
@ -759,73 +757,67 @@ QtObject:
|
|||
self.threadpool.start(arg)
|
||||
|
||||
proc emitAddKeycardAddAccountsChange(self: Service, success: bool, keycard: KeycardDto) =
|
||||
let data = KeycardActivityArgs(
|
||||
let data = KeycardArgs(
|
||||
success: success,
|
||||
keycard: keycard
|
||||
)
|
||||
self.events.emit(SIGNAL_NEW_KEYCARD_SET, data)
|
||||
|
||||
proc onKeycardAdded*(self: Service, response: string) {.slot.} =
|
||||
var keycard = KeycardDto()
|
||||
var success = false
|
||||
try:
|
||||
let responseObj = response.parseJson
|
||||
var keycard: KeycardDto
|
||||
var success = false
|
||||
discard responseObj.getProp("success", success)
|
||||
if success:
|
||||
var kpJson: JsonNode
|
||||
if responseObj.getProp("keycard", kpJson):
|
||||
keycard = kpJson.toKeycardDto()
|
||||
self.emitAddKeycardAddAccountsChange(success, keycard)
|
||||
var kpJson: JsonNode
|
||||
if responseObj.getProp("keycard", kpJson):
|
||||
keycard = kpJson.toKeycardDto()
|
||||
except Exception as e:
|
||||
error "error handilng migrated keycard response", errDesription=e.msg
|
||||
self.emitAddKeycardAddAccountsChange(success = false, KeycardDto())
|
||||
self.emitAddKeycardAddAccountsChange(success, keycard)
|
||||
|
||||
proc addKeycardOrAccounts*(self: Service, keycard: KeycardDto, accountsComingFromKeycard: bool = false): bool =
|
||||
var success = false
|
||||
try:
|
||||
let response = backend.addKeycardOrAddAccountsIfKeycardIsAdded(
|
||||
keycard.keycardUid,
|
||||
keycard.keycardName,
|
||||
keycard.keyUid,
|
||||
keycard.accountsAddresses,
|
||||
let response = backend.saveOrUpdateKeycard(
|
||||
%* {
|
||||
"keycard-uid": keycard.keycardUid,
|
||||
"keycard-name": keycard.keycardName,
|
||||
# "keycard-locked" - no need to set it here, cause it will be set to false by the status-go
|
||||
"key-uid": keycard.keyUid,
|
||||
"accounts-addresses": keycard.accountsAddresses,
|
||||
# "position": - no need to set it here, cause it is fully maintained by the status-go
|
||||
},
|
||||
accountsComingFromKeycard
|
||||
)
|
||||
result = responseHasNoErrors("addKeycardOrAccounts", response)
|
||||
if result:
|
||||
self.emitAddKeycardAddAccountsChange(success = true, keycard)
|
||||
success = responseHasNoErrors("addKeycardOrAccounts", response)
|
||||
except Exception as e:
|
||||
error "error: ", procName="addKeycardOrAccounts", errName = e.name, errDesription = e.msg
|
||||
self.emitAddKeycardAddAccountsChange(success = success, keycard)
|
||||
return success
|
||||
|
||||
proc removeMigratedAccountsForKeycard*(self: Service, keyUid: string, keycardUid: string, accountsToRemove: seq[string]) =
|
||||
let arg = RemoveMigratedAccountsForKeycardTaskArg(
|
||||
tptr: cast[ByteAddress](removeMigratedAccountsForKeycardTask),
|
||||
let arg = DeleteKeycardAccountsTaskArg(
|
||||
tptr: cast[ByteAddress](deleteKeycardAccountsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onMigratedAccountsForKeycardRemoved",
|
||||
keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid, accountsAddresses: accountsToRemove)
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc emitKeycardRemovedAccountsChange(self: Service, success: bool, keyUid: string, keycardUid: string,
|
||||
removedAccounts: seq[string]) =
|
||||
let data = KeycardActivityArgs(
|
||||
success: success,
|
||||
keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid, accountsAddresses: removedAccounts)
|
||||
)
|
||||
self.events.emit(SIGNAL_KEYCARD_ACCOUNTS_REMOVED, data)
|
||||
|
||||
proc onMigratedAccountsForKeycardRemoved*(self: Service, response: string) {.slot.} =
|
||||
var data = KeycardArgs(
|
||||
success: false,
|
||||
)
|
||||
try:
|
||||
let responseObj = response.parseJson
|
||||
var keycard: KeycardDto
|
||||
var success = false
|
||||
discard responseObj.getProp("success", success)
|
||||
if success:
|
||||
var kpJson: JsonNode
|
||||
if responseObj.getProp("keycard", kpJson):
|
||||
keycard = kpJson.toKeycardDto()
|
||||
self.emitKeycardRemovedAccountsChange(success, keycard.keyUid, keycard.keycardUid, keycard.accountsAddresses)
|
||||
discard responseObj.getProp("success", data.success)
|
||||
var kpJson: JsonNode
|
||||
if responseObj.getProp("keycard", kpJson):
|
||||
data.keycard = kpJson.toKeycardDto()
|
||||
except Exception as e:
|
||||
error "error handilng migrated keycard response", errDesription=e.msg
|
||||
self.emitKeycardRemovedAccountsChange(success = false, keyUid = "", keycardUid = "", removedAccounts = @[])
|
||||
self.events.emit(SIGNAL_KEYCARD_ACCOUNTS_REMOVED, data)
|
||||
|
||||
proc getAllKnownKeycards*(self: Service): seq[KeycardDto] =
|
||||
try:
|
||||
|
@ -835,31 +827,21 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "error: ", procName="getAllKnownKeycards", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc getKeycardWithKeycardUid*(self: Service, keycardUid: string): KeycardDto =
|
||||
let allKnownKeycards = self.getAllKnownKeycards()
|
||||
let keycardsWithKeycardUid = allKnownKeycards.filter(kp => kp.keycardUid == keycardUid)
|
||||
if keycardsWithKeycardUid.len == 0:
|
||||
return
|
||||
if keycardsWithKeycardUid.len > 1:
|
||||
error "there are more than one keycard with the same uid", keycardUid=keycardUid
|
||||
return
|
||||
return keycardsWithKeycardUid[0]
|
||||
|
||||
proc getAllKnownKeycardsGroupedByKeyUid*(self: Service): seq[KeycardDto] =
|
||||
proc getKeycardByKeycardUid*(self: Service, keycardUid: string): KeycardDto =
|
||||
try:
|
||||
let response = backend.getAllKnownKeycardsGroupedByKeyUid()
|
||||
if responseHasNoErrors("getAllKnownKeycardsGroupedByKeyUid", response):
|
||||
let response = backend.getKeycardByKeycardUID(keycardUid)
|
||||
if responseHasNoErrors("getKeycardByKeycardUid", response):
|
||||
return response.result.toKeycardDto()
|
||||
except Exception as e:
|
||||
error "error: ", procName="getKeycardByKeycardUid", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc getKeycardsWithSameKeyUid*(self: Service, keyUid: string): seq[KeycardDto] =
|
||||
try:
|
||||
let response = backend.getKeycardsWithSameKeyUID(keyUid)
|
||||
if responseHasNoErrors("getKeycardsWithSameKeyUid", response):
|
||||
return map(response.result.getElems(), proc(x: JsonNode): KeycardDto = toKeycardDto(x))
|
||||
except Exception as e:
|
||||
error "error: ", procName="getAllKnownKeycardsGroupedByKeyUid", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc getKeycardByKeyUid*(self: Service, keyUid: string): seq[KeycardDto] =
|
||||
try:
|
||||
let response = backend.getKeycardByKeyUid(keyUid)
|
||||
if responseHasNoErrors("getKeycardByKeyUid", response):
|
||||
return map(response.result.getElems(), proc(x: JsonNode): KeycardDto = toKeycardDto(x))
|
||||
except Exception as e:
|
||||
error "error: ", procName="getKeycardByKeyUid", errName = e.name, errDesription = e.msg
|
||||
error "error: ", procName="getKeycardsWithSameKeyUid", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc isKeycardAccount*(self: Service, account: WalletAccountDto): bool =
|
||||
if account.isNil or
|
||||
|
@ -867,108 +849,84 @@ QtObject:
|
|||
account.path.len == 0 or
|
||||
utils.isPathOutOfTheDefaultStatusDerivationTree(account.path):
|
||||
return false
|
||||
let keycards = self.getKeycardByKeyUid(account.keyUid)
|
||||
let keycards = self.getKeycardsWithSameKeyUid(account.keyUid)
|
||||
return keycards.len > 0
|
||||
|
||||
proc emitKeycardNameChange(self: Service, keycardUid: string, name: string) =
|
||||
let data = KeycardActivityArgs(success: true, keycard: KeycardDto(keycardUid: keycardUid, keycardName: name))
|
||||
self.events.emit(SIGNAL_KEYCARD_NAME_CHANGED, data)
|
||||
|
||||
proc updateKeycardName*(self: Service, keycardUid: string, name: string): bool =
|
||||
var data = KeycardArgs(
|
||||
success: false,
|
||||
keycard: KeycardDto(keycardUid: keycardUid, keycardName: name)
|
||||
)
|
||||
try:
|
||||
let response = backend.setKeycardName(keycardUid, name)
|
||||
result = responseHasNoErrors("updateKeycardName", response)
|
||||
if result:
|
||||
self.emitKeycardNameChange(keycardUid, name)
|
||||
data.success = responseHasNoErrors("updateKeycardName", response)
|
||||
except Exception as e:
|
||||
error "error: ", procName="updateKeycardName", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc emitKeycardLockedChange(self: Service, keyUid: string, keycardUid: string) =
|
||||
let data = KeycardActivityArgs(success: true, keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid))
|
||||
self.events.emit(SIGNAL_KEYCARD_LOCKED, data)
|
||||
self.events.emit(SIGNAL_KEYCARD_NAME_CHANGED, data)
|
||||
return data.success
|
||||
|
||||
proc setKeycardLocked*(self: Service, keyUid: string, keycardUid: string): bool =
|
||||
var data = KeycardArgs(
|
||||
success: false,
|
||||
keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid)
|
||||
)
|
||||
try:
|
||||
let response = backend.keycardLocked(keycardUid)
|
||||
result = responseHasNoErrors("setKeycardLocked", response)
|
||||
if result:
|
||||
self.emitKeycardLockedChange(keyUid, keycardUid)
|
||||
data.success = responseHasNoErrors("setKeycardLocked", response)
|
||||
except Exception as e:
|
||||
error "error: ", procName="setKeycardLocked", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc emitKeycardUnlockedChange(self: Service, keyUid: string, keycardUid: string) =
|
||||
let data = KeycardActivityArgs(success: true, keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid))
|
||||
self.events.emit(SIGNAL_KEYCARD_UNLOCKED, data)
|
||||
self.events.emit(SIGNAL_KEYCARD_LOCKED, data)
|
||||
return data.success
|
||||
|
||||
proc setKeycardUnlocked*(self: Service, keyUid: string, keycardUid: string): bool =
|
||||
var data = KeycardArgs(
|
||||
success: false,
|
||||
keycard: KeycardDto(keyUid: keyUid, keycardUid: keycardUid)
|
||||
)
|
||||
try:
|
||||
let response = backend.keycardUnlocked(keycardUid)
|
||||
result = responseHasNoErrors("setKeycardUnlocked", response)
|
||||
if result:
|
||||
self.emitKeycardUnlockedChange(keyUid, keycardUid)
|
||||
data.success = responseHasNoErrors("setKeycardUnlocked", response)
|
||||
except Exception as e:
|
||||
error "error: ", procName="setKeycardUnlocked", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc emitUpdateKeycardUidChange(self: Service, oldKeycardUid: string, newKeycardUid: string) =
|
||||
let data = KeycardActivityArgs(success: true, oldKeycardUid: oldKeycardUid, keycard: KeycardDto(keycardUid: newKeycardUid))
|
||||
self.events.emit(SIGNAL_KEYCARD_UID_UPDATED, data)
|
||||
self.events.emit(SIGNAL_KEYCARD_UNLOCKED, data)
|
||||
return data.success
|
||||
|
||||
proc updateKeycardUid*(self: Service, oldKeycardUid: string, newKeycardUid: string): bool =
|
||||
var data = KeycardArgs(
|
||||
success: false,
|
||||
oldKeycardUid: oldKeycardUid,
|
||||
keycard: KeycardDto(keycardUid: newKeycardUid)
|
||||
)
|
||||
try:
|
||||
let response = backend.updateKeycardUID(oldKeycardUid, newKeycardUid)
|
||||
result = responseHasNoErrors("updateKeycardUid", response)
|
||||
if result:
|
||||
self.emitUpdateKeycardUidChange(oldKeycardUid, newKeycardUid)
|
||||
data.success = responseHasNoErrors("updateKeycardUid", response)
|
||||
except Exception as e:
|
||||
error "error: ", procName="updateKeycardUid", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc emitDeleteKeycardChange(self: Service, keycardUid: string) =
|
||||
let data = KeycardActivityArgs(success: true, keycard: KeycardDto(keycardUid: keycardUid))
|
||||
self.events.emit(SIGNAL_KEYCARD_DELETED, data)
|
||||
self.events.emit(SIGNAL_KEYCARD_UID_UPDATED, data)
|
||||
return data.success
|
||||
|
||||
proc deleteKeycard*(self: Service, keycardUid: string): bool =
|
||||
var data = KeycardArgs(
|
||||
success: false,
|
||||
keycard: KeycardDto(keycardUid: keycardUid)
|
||||
)
|
||||
try:
|
||||
let response = backend.deleteKeycard(keycardUid)
|
||||
result = responseHasNoErrors("deleteKeycard", response)
|
||||
if result:
|
||||
self.emitDeleteKeycardChange(keycardUid)
|
||||
data.success = responseHasNoErrors("deleteKeycard", response)
|
||||
except Exception as e:
|
||||
error "error: ", procName="deleteKeycard", errName = e.name, errDesription = e.msg
|
||||
return false
|
||||
self.events.emit(SIGNAL_KEYCARD_DELETED, data)
|
||||
return data.success
|
||||
|
||||
proc handleWalletAccount(self: Service, account: WalletAccountDto) =
|
||||
proc handleWalletAccount(self: Service, account: WalletAccountDto, notify: bool = true) =
|
||||
if account.removed:
|
||||
self.removeAccountFromLocalStoreAndNotify(account.address)
|
||||
self.removeAccountFromLocalStoreAndNotify(account.address, notify)
|
||||
else:
|
||||
if self.walletAccountsContainsAddress(account.address):
|
||||
self.updateAccountInLocalStoreAndNotify(account.address, account.name, account.colorId, account.emoji, account.position)
|
||||
self.updateAccountInLocalStoreAndNotify(account.address, account.name, account.colorId, account.emoji,
|
||||
some(account.position), notify)
|
||||
else:
|
||||
self.addNewAccountToLocalStoreAndNotify()
|
||||
|
||||
proc handleKeycardActions(self: Service, keycardActions: seq[KeycardActionDto]) =
|
||||
if keycardActions.len == 0:
|
||||
return
|
||||
for kcAction in keycardActions:
|
||||
if kcAction.action == KeycardActionKeycardAdded or
|
||||
kcAction.action == KeycardActionAccountsAdded:
|
||||
self.emitAddKeycardAddAccountsChange(success = true, kcAction.keycard)
|
||||
elif kcAction.action == KeycardActionKeycardDeleted:
|
||||
self.emitDeleteKeycardChange(kcAction.keycard.keycardUid)
|
||||
elif kcAction.action == KeycardActionAccountsRemoved:
|
||||
let keycard = self.getKeycardWithKeycardUid(kcAction.keycard.keycardUid)
|
||||
self.emitKeycardRemovedAccountsChange(success = true, keycard.keyUid, kcAction.keycard.keycardUid, kcAction.keycard.accountsAddresses)
|
||||
elif kcAction.action == KeycardActionLocked:
|
||||
let keycard = self.getKeycardWithKeycardUid(kcAction.keycard.keycardUid)
|
||||
self.emitKeycardLockedChange(keycard.keyUid, kcAction.keycard.keycardUid)
|
||||
elif kcAction.action == KeycardActionUnlocked:
|
||||
let keycard = self.getKeycardWithKeycardUid(kcAction.keycard.keycardUid)
|
||||
self.emitKeycardUnlockedChange(keycard.keyUid, kcAction.keycard.keycardUid)
|
||||
elif kcAction.action == KeycardActionUidUpdated:
|
||||
self.emitUpdateKeycardUidChange(kcAction.oldKeycardUid, kcAction.keycard.keycardUid)
|
||||
elif kcAction.action == KeycardActionNameChanged:
|
||||
self.emitKeycardNameChange(kcAction.keycard.keycardUid, kcAction.keycard.keycardName)
|
||||
else:
|
||||
error "unsupported action received", action=kcAction.action
|
||||
self.addNewAccountToLocalStoreAndNotify(notify)
|
||||
|
||||
proc handleKeypair(self: Service, keypair: KeypairDto) =
|
||||
## In some point in future instead `self.walletAccounts` table we should switch to maintaining local state in the
|
||||
|
@ -984,16 +942,13 @@ QtObject:
|
|||
for localAcc in localKeypairRelatedAccounts:
|
||||
let accAddress = localAcc.address
|
||||
if keypair.accounts.filter(a => cmpIgnoreCase(a.address, accAddress) == 0).len == 0:
|
||||
self.handleWalletAccount(WalletAccountDto(address: accAddress, removed: true))
|
||||
self.handleWalletAccount(WalletAccountDto(address: accAddress, removed: true), notify = false)
|
||||
# - second add/update new/existing accounts
|
||||
for acc in keypair.accounts:
|
||||
self.handleWalletAccount(acc)
|
||||
self.handleWalletAccount(acc, notify = false)
|
||||
|
||||
if keypair.removed:
|
||||
self.events.emit(SIGNAL_KEYPAIR_DELETED, KeypairArgs(keypair: keypair))
|
||||
else:
|
||||
# notify all interested parts about the keypair change
|
||||
self.events.emit(SIGNAL_KEYPAIR_CHANGED, KeypairArgs(keypair: keypair))
|
||||
# notify all interested parts about the keypair change
|
||||
self.events.emit(SIGNAL_KEYPAIR_SYNCED, KeypairArgs(keypair: keypair))
|
||||
|
||||
proc allAccountsTokenBalance*(self: Service, symbol: string): float64 =
|
||||
var totalTokenBalance = 0.0
|
||||
|
|
|
@ -221,26 +221,23 @@ rpc(fetchMarketValues, "wallet"):
|
|||
rpc(fetchTokenDetails, "wallet"):
|
||||
symbols: seq[string]
|
||||
|
||||
rpc(addKeycardOrAddAccountsIfKeycardIsAdded, "accounts"):
|
||||
keycardUid: string
|
||||
keyPairName: string
|
||||
keyUid: string
|
||||
accountAddresses: seq[string]
|
||||
rpc(saveOrUpdateKeycard, "accounts"):
|
||||
keycard: JsonNode
|
||||
accountsComingFromKeycard: bool
|
||||
|
||||
rpc(removeMigratedAccountsForKeycard, "accounts"):
|
||||
rpc(deleteKeycardAccounts, "accounts"):
|
||||
keycardUid: string
|
||||
accountsToRemove: seq[string]
|
||||
|
||||
rpc(getAllKnownKeycards, "accounts"):
|
||||
discard
|
||||
|
||||
rpc(getAllKnownKeycardsGroupedByKeyUID, "accounts"):
|
||||
discard
|
||||
|
||||
rpc(getKeycardByKeyUID, "accounts"):
|
||||
rpc(getKeycardsWithSameKeyUID, "accounts"):
|
||||
keyUid: string
|
||||
|
||||
rpc(getKeycardByKeycardUID, "accounts"):
|
||||
keycardUid: string
|
||||
|
||||
rpc(setKeycardName, "accounts"):
|
||||
keycardUid: string
|
||||
keyPairName: string
|
||||
|
|
|
@ -88,6 +88,11 @@ SettingsContentBase {
|
|||
onChangeSectionTitle: {
|
||||
root.sectionTitle = title
|
||||
}
|
||||
|
||||
onDetailsModelIsEmpty: {
|
||||
// if keypair is removed while user is in the details keycard view mode we need to go back to main keycard view
|
||||
root.handleBackAction()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
|
@ -19,12 +19,22 @@ ColumnLayout {
|
|||
property string keyUid: ""
|
||||
|
||||
signal changeSectionTitle(string title)
|
||||
signal detailsModelIsEmpty()
|
||||
|
||||
spacing: Constants.settingsSection.itemSpacing
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property bool collapsed: true
|
||||
readonly property int numOfKeycards: root.keycardStore.keycardModule.keycardDetailsModel?
|
||||
root.keycardStore.keycardModule.keycardDetailsModel.count
|
||||
: 0
|
||||
|
||||
onNumOfKeycardsChanged: {
|
||||
if (!!root.keycardStore.keycardModule.keycardDetailsModel && numOfKeycards === 0) {
|
||||
root.detailsModelIsEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
function checkAndCheckTitleIfNeeded(newKeycardName) {
|
||||
// We change title if there is only a single keycard for a keypair in keycard details view
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 61527f8c7870331bc3c6b61f3adb1c68111e9188
|
||||
Subproject commit 7063ad11aabf5f6ccb1db4b12e55b69292fd9707
|
Loading…
Reference in New Issue