From fb39c8c3b88f85518481924948d70cd0e172e844 Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Fri, 5 Jan 2024 21:17:58 +0530 Subject: [PATCH] fix(@desktop/wallet): Switching networks doesn't change assets fixes #13137, #13144 --- .../assets/grouped_account_assets_model.nim | 12 ++++++-- .../main/wallet_section/assets/module.nim | 2 -- .../main/wallet_section/assets/view.nim | 13 --------- .../modules/main/wallet_section/module.nim | 5 ++++ src/app/modules/main/wallet_section/view.nim | 10 +++++-- src/app_service/service/token/service.nim | 1 - .../wallet_account/dto/account_token_item.nim | 24 ++------------- .../service/wallet_account/service.nim | 2 +- .../wallet_account/service_account.nim | 23 ++++++++++++++- .../service/wallet_account/service_token.nim | 3 ++ .../wallet_account/service_token_new.nim | 29 ++++++++++--------- ui/app/AppLayouts/Wallet/stores/RootStore.qml | 1 - .../AppLayouts/Wallet/views/RightTabView.qml | 2 +- ui/imports/shared/views/AssetsView.qml | 7 +++-- 14 files changed, 71 insertions(+), 63 deletions(-) diff --git a/src/app/modules/main/wallet_section/assets/grouped_account_assets_model.nim b/src/app/modules/main/wallet_section/assets/grouped_account_assets_model.nim index 7478e78515..af03abceee 100644 --- a/src/app/modules/main/wallet_section/assets/grouped_account_assets_model.nim +++ b/src/app/modules/main/wallet_section/assets/grouped_account_assets_model.nim @@ -59,10 +59,16 @@ QtObject: result = newQVariant(self.balancesPerChain[index.row]) proc modelsAboutToUpdate*(self: Model) = - self.balancesPerChain = @[] self.beginResetModel() proc modelsUpdated*(self: Model) = - for i in countup(0, (self.delegate.getGroupedAccountsAssetsList().len-1)): - self.balancesPerChain.add(newBalancesModel(self.delegate, i)) + let lengthOfGroupedAssets = self.delegate.getGroupedAccountsAssetsList().len + let balancesPerChainLen = self.balancesPerChain.len + let diff = abs(lengthOfGroupedAssets - balancesPerChainLen) + if lengthOfGroupedAssets > balancesPerChainLen: + for i in countup(0, diff-1): + self.balancesPerChain.add(newBalancesModel(self.delegate, balancesPerChainLen+i)) + elif lengthOfGroupedAssets < balancesPerChainLen: + self.balancesPerChain.delete(balancesPerChainLen - diff, balancesPerChainLen-1) self.endResetModel() + self.countChanged() diff --git a/src/app/modules/main/wallet_section/assets/module.nim b/src/app/modules/main/wallet_section/assets/module.nim index 2ca310e974..189a085e47 100644 --- a/src/app/modules/main/wallet_section/assets/module.nim +++ b/src/app/modules/main/wallet_section/assets/module.nim @@ -60,7 +60,6 @@ method load*(self: Module) = self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args): let arg = TokensPerAccountArgs(e) self.view.modelsUpdated() - self.view.setAssetsLoading(false) self.view.setHasBalanceCache(self.controller.getHasBalanceCache()) self.view.setHasMarketValuesCache(self.controller.getHasMarketValuesCache()) @@ -105,7 +104,6 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) let walletAccounts = self.controller.getWalletAccountsByAddresses(addresses) if walletAccounts[0].assetsLoading: - self.view.setAssetsLoading(true) self.setLoadingAssets() else: let walletTokens = self.controller.getWalletTokensByAddresses(addresses) diff --git a/src/app/modules/main/wallet_section/assets/view.nim b/src/app/modules/main/wallet_section/assets/view.nim index 30a6e7fce8..59691fa176 100644 --- a/src/app/modules/main/wallet_section/assets/view.nim +++ b/src/app/modules/main/wallet_section/assets/view.nim @@ -11,7 +11,6 @@ QtObject: delegate: io_interface.AccessInterface assets: token_model.Model groupedAccountAssetsModel: grouped_account_assets_model.Model - assetsLoading: bool hasBalanceCache: bool hasMarketValuesCache: bool @@ -49,18 +48,6 @@ QtObject: read = getGroupedAccountAssetsModel notify = groupedAccountAssetsModelChanged - proc getAssetsLoading(self: View): QVariant {.slot.} = - return newQVariant(self.assetsLoading) - proc assetsLoadingChanged(self: View) {.signal.} - QtProperty[QVariant] assetsLoading: - read = getAssetsLoading - notify = assetsLoadingChanged - - proc setAssetsLoading*(self:View, assetLoading: bool) = - if assetLoading != self.assetsLoading: - self.assetsLoading = assetLoading - self.assetsLoadingChanged() - proc getHasBalanceCache(self: View): QVariant {.slot.} = return newQVariant(self.hasBalanceCache) proc hasBalanceCacheChanged(self: View) {.signal.} diff --git a/src/app/modules/main/wallet_section/module.nim b/src/app/modules/main/wallet_section/module.nim index 6ac76a7a09..1153d85ca4 100644 --- a/src/app/modules/main/wallet_section/module.nim +++ b/src/app/modules/main/wallet_section/module.nim @@ -185,6 +185,7 @@ proc notifyFilterChanged(self: Module) = self.activityController.globalFilterChanged(self.filter.addresses, self.filter.allAddresses, self.filter.chainIds, self.filter.allChainsEnabled) self.collectiblesController.setFilterAddressesAndChains(self.filter.addresses, self.filter.chainIds) self.allTokensModule.filterChanged(self.filter.addresses) + self.view.setAddressFilters(self.filter.addresses.join(":")) if self.filter.addresses.len > 0: self.view.filterChanged(self.filter.addresses[0], self.filter.allAddresses) @@ -273,6 +274,10 @@ method load*(self: Module) = self.notifyFilterChanged() self.setTotalCurrencyBalance() + self.events.on(SIGNAL_CURRENCY_UPDATED) do(e:Args): + let args = SettingsTextValueArgs(e) + self.view.setCurrentCurrency(args.value) + self.controller.init() self.view.load() self.accountsModule.load() diff --git a/src/app/modules/main/wallet_section/view.nim b/src/app/modules/main/wallet_section/view.nim index ce4f281182..7f07f8b4bf 100644 --- a/src/app/modules/main/wallet_section/view.nim +++ b/src/app/modules/main/wallet_section/view.nim @@ -25,6 +25,7 @@ QtObject: wcController: wcc.Controller walletReady: bool addressFilters: string + currentCurrency: string proc setup(self: View) = self.QObject.setup @@ -46,12 +47,17 @@ QtObject: proc load*(self: View) = self.delegate.viewDidLoad() + proc currentCurrencyChanged*(self: View) {.signal.} proc updateCurrency*(self: View, currency: string) {.slot.} = self.delegate.updateCurrency(currency) + proc setCurrentCurrency*(self: View, currency: string) = + self.currentCurrency = currency + self.currentCurrencyChanged() proc getCurrentCurrency(self: View): string {.slot.} = return self.delegate.getCurrentCurrency() QtProperty[string] currentCurrency: read = getCurrentCurrency + notify = currentCurrencyChanged proc filterChanged*(self: View, addresses: string, allAddresses: bool) {.signal.} @@ -77,7 +83,7 @@ QtObject: read = getIsMnemonicBackedUp proc addressFiltersChanged*(self: View) {.signal.} - proc setAddressFilters(self: View, address: string) = + proc setAddressFilters*(self: View, address: string) = self.addressFilters = address self.addressFiltersChanged() proc getAddressFilters(self: View): string {.slot.} = @@ -87,11 +93,9 @@ QtObject: notify = addressFiltersChanged proc setFilterAddress(self: View, address: string) {.slot.} = - self.setAddressFilters(address) self.delegate.setFilterAddress(address) proc setFillterAllAddresses(self: View) {.slot.} = - self.setAddressFilters("") self.delegate.setFillterAllAddresses() proc setTotalCurrencyBalance*(self: View, totalCurrencyBalance: CurrencyAmount) = diff --git a/src/app_service/service/token/service.nim b/src/app_service/service/token/service.nim index 454df1545e..9b074bbd60 100644 --- a/src/app_service/service/token/service.nim +++ b/src/app_service/service/token/service.nim @@ -450,7 +450,6 @@ QtObject: if symbols.len > 0: self.fetchTokensMarketValues(symbols) self.fetchTokensPrices(symbols) - self.fetchTokensDetails(symbols) proc getTokenByFlatTokensKey*(self: Service, key: string): TokenItem = for t in self.flatTokenList: diff --git a/src/app_service/service/wallet_account/dto/account_token_item.nim b/src/app_service/service/wallet_account/dto/account_token_item.nim index 20ec4ab9b9..db14fadb07 100644 --- a/src/app_service/service/wallet_account/dto/account_token_item.nim +++ b/src/app_service/service/wallet_account/dto/account_token_item.nim @@ -1,24 +1,6 @@ -import stint,strformat +import stint, strformat -type - AccountTokenItem* = object - key*: string - flatTokensKey*: string - symbol*: string - account*: string - chainId*: int - balance*: Uint256 - -proc `$`*(self: AccountTokenItem): string = - result = fmt"""AccountTokenItem[ - key: {self.key}, - flatTokensKey: {self.flatTokensKey}, - symbol: {self.symbol}, - account: {self.account}, - chainId: {self.chainId}, - balance: {self.balance}]""" - -type BalanceItem* = object +type BalanceItem* = ref object of RootObj account*: string chainId*: int balance*: Uint256 @@ -30,7 +12,7 @@ proc `$`*(self: BalanceItem): string = balance: {self.balance}]""" type - GroupedTokenItem* = object + GroupedTokenItem* = ref object of RootObj tokensKey*: string symbol*: string balancesPerAccount*: seq[BalanceItem] diff --git a/src/app_service/service/wallet_account/service.nim b/src/app_service/service/wallet_account/service.nim index 893e0c7626..8ac58a7398 100644 --- a/src/app_service/service/wallet_account/service.nim +++ b/src/app_service/service/wallet_account/service.nim @@ -47,7 +47,7 @@ QtObject: keypairs: Table[string, KeypairDto] ## [keyUid, KeypairDto] accountsTokens*: Table[string, seq[WalletTokenDto]] ## [address, seq[WalletTokenDto]] - flatAccountTokensList: seq[AccountTokenItem] + groupedAccountsTokensTable: Table[string, GroupedTokenItem] groupedAccountsTokensList: seq[GroupedTokenItem] hasBalanceCache: bool diff --git a/src/app_service/service/wallet_account/service_account.nim b/src/app_service/service/wallet_account/service_account.nim index b8e65d7497..7adc58c14f 100644 --- a/src/app_service/service/wallet_account/service_account.nim +++ b/src/app_service/service/wallet_account/service_account.nim @@ -173,10 +173,16 @@ proc init*(self: Service) = of "wallet-tick-reload": let addresses = self.getWalletAddresses() self.buildAllTokens(addresses, store = true) + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 + self.newBuildAllTokens(addresses, store = true) self.checkRecentHistory(addresses) self.events.on(SIGNAL_CURRENCY_UPDATED) do(e:Args): + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(self.getWalletAddresses(), store = true) + self.newBuildAllTokens(self.getWalletAddresses(), store = true) self.events.on(SIGNAL_IMPORT_PARTIALLY_OPERABLE_ACCOUNTS) do(e: Args): let args = ImportAccountsArgs(e) @@ -197,7 +203,10 @@ proc addNewKeypairsAccountsToLocalStoreAndNotify(self: Service, notify: bool = t continue woAccDb.ens = getEnsName(woAccDb.address, chainId) self.storeWatchOnlyAccount(woAccDb) + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(@[woAccDb.address], store = true) + self.newBuildAllTokens(@[woAccDb.address], store = true) if notify: self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountArgs(account: woAccDb)) # check if there is new keypair or any account added to an existing keypair @@ -207,7 +216,10 @@ proc addNewKeypairsAccountsToLocalStoreAndNotify(self: Service, notify: bool = t if localKp.isNil: self.storeKeypair(kpDb) let addresses = kpDb.accounts.map(a => a.address) + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(addresses, store = true) + self.newBuildAllTokens(addresses, store = true) for acc in kpDb.accounts: acc.ens = getEnsName(acc.address, chainId) if acc.isChat: @@ -227,7 +239,10 @@ proc addNewKeypairsAccountsToLocalStoreAndNotify(self: Service, notify: bool = t self.storeAccountToKeypair(accDb) if accDb.isChat: continue + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(@[accDb.address], store = true) + self.newBuildAllTokens(@[accDb.address], store = true) if notify: self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountArgs(account: accDb)) @@ -525,7 +540,10 @@ proc setNetworksState*(self: Service, chainIds: seq[int], enabled: bool) = proc toggleTestNetworksEnabled*(self: Service) = discard self.settingsService.toggleTestNetworksEnabled() let addresses = self.getWalletAddresses() + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(addresses, store = true) + self.newBuildAllTokens(addresses, store = true) self.tokenService.loadData() self.checkRecentHistory(addresses) self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, Args()) @@ -534,7 +552,10 @@ proc toggleIsSepoliaEnabled*(self: Service) = discard self.settingsService.toggleIsSepoliaEnabled() self.networkService.resetNetworks() let addresses = self.getWalletAddresses() + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(addresses, store = true) + self.newBuildAllTokens(addresses, store = true) self.tokenService.loadData() self.checkRecentHistory(addresses) self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, Args()) @@ -789,4 +810,4 @@ proc addressWasShown*(self: Service, address: string) = if not response.error.isNil: raise newException(CatchableError, response.error.message) except Exception as e: - error "error: ", procName="addressWasShown", errName=e.name, errDesription=e.msg \ No newline at end of file + error "error: ", procName="addressWasShown", errName=e.name, errDesription=e.msg diff --git a/src/app_service/service/wallet_account/service_token.nim b/src/app_service/service/wallet_account/service_token.nim index 934e44fc68..03b561a84a 100644 --- a/src/app_service/service/wallet_account/service_token.nim +++ b/src/app_service/service/wallet_account/service_token.nim @@ -100,7 +100,10 @@ proc checkRecentHistory*(self: Service, addresses: seq[string]) = proc reloadAccountTokens*(self: Service) = let addresses = self.getWalletAddresses() + # TODO: Only the newBuildAllTokens will remain after task - + # https://github.com/status-im/status-desktop/issues/13142 self.buildAllTokens(addresses, store = true) + self.newBuildAllTokens(addresses, store = true) self.checkRecentHistory(addresses) proc getCurrency*(self: Service): string = diff --git a/src/app_service/service/wallet_account/service_token_new.nim b/src/app_service/service/wallet_account/service_token_new.nim index 6c0a53a19d..3b6c989d3a 100644 --- a/src/app_service/service/wallet_account/service_token_new.nim +++ b/src/app_service/service/wallet_account/service_token_new.nim @@ -8,11 +8,22 @@ proc onNewAllTokensBuilt*(self: Service, response: string) {.slot.} = discard responseObj.getProp("storeResult", storeResult) discard responseObj.getProp("result", resultObj) - var accountsTokensBalances: seq[AccountTokenItem] = @[] - var groupedAccountsTokensBalances: Table[string, GroupedTokenItem] = initTable[string, GroupedTokenItem]() + var groupedAccountsTokensBalances = self.groupedAccountsTokensTable var allTokensHaveError: bool = true if resultObj.kind == JObject: for accountAddress, tokensDetailsObj in resultObj: + + # Delete all existing entries for the account for whom assets were requested, + # for a new account the balances per address per chain will simply be appended later + var tokensToBeDeleted: seq[string] = @[] + for tokenkey, token in groupedAccountsTokensBalances: + token.balancesPerAccount = token.balancesPerAccount.filter(balanceItem => balanceItem.account != accountAddress) + if token.balancesPerAccount.len == 0: + tokensToBeDeleted.add(tokenkey) + + for t in tokensToBeDeleted: + groupedAccountsTokensBalances.del(t) + if tokensDetailsObj.kind == JArray: for token in tokensDetailsObj.getElems(): @@ -47,22 +58,12 @@ proc onNewAllTokensBuilt*(self: Service, response: string) {.slot.} = balancesPerAccount: @[BalanceItem(account:accountAddress, chainId: chainId, balance: rawBalance)] ) - accountsTokensBalances.add(AccountTokenItem( - key: flatTokensKey & accountAddress, - symbol: symbol, - flatTokensKey: flatTokensKey, - account: accountAddress, - chainId: chainId, - balance: rawBalance - )) - # set assetsLoading to false once the tokens are loaded self.updateAssetsLoadingState(accountAddress, false) if storeResult and not allTokensHaveError: self.hasBalanceCache = true - self.flatAccountTokensList = accountsTokensBalances + self.groupedAccountsTokensTable = groupedAccountsTokensBalances self.groupedAccountsTokensList = toSeq(groupedAccountsTokensBalances.values) - except Exception as e: error "error: ", procName="onAllTokensBuilt", errName = e.name, errDesription = e.msg @@ -89,7 +90,7 @@ proc newBuildAllTokens*(self: Service, accounts: seq[string], store: bool) = proc getTotalCurrencyBalance*(self: Service, addresses: seq[string], chainIds: seq[int]): float64 = var totalBalance: float64 = 0.0 - for token in self.groupedAccountsTokensList: + for tokensKey, token in self.groupedAccountsTokensList: let price = self.tokenService.getPriceBySymbol(token.symbol) let balances = token.balancesPerAccount.filter(a => addresses.contains(a.account) and chainIds.contains(a.chainId)) for balance in balances: diff --git a/ui/app/AppLayouts/Wallet/stores/RootStore.qml b/ui/app/AppLayouts/Wallet/stores/RootStore.qml index c97ab80473..ed992766b4 100644 --- a/ui/app/AppLayouts/Wallet/stores/RootStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/RootStore.qml @@ -37,7 +37,6 @@ QtObject { property string backButtonName: "" property var overview: walletSectionOverview property var assets: walletSectionAssets.assets - property bool assetsLoading: walletSectionAssets.assetsLoading property bool balanceLoading: overview.balanceLoading property var accounts: walletSectionAccounts.accounts property var receiveAccounts: walletSectionSend.accounts diff --git a/ui/app/AppLayouts/Wallet/views/RightTabView.qml b/ui/app/AppLayouts/Wallet/views/RightTabView.qml index 68c54846cf..3c22435369 100644 --- a/ui/app/AppLayouts/Wallet/views/RightTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/RightTabView.qml @@ -128,7 +128,7 @@ RightTabBaseView { currentIndex: walletTabBar.currentIndex AssetsView { - areAssetsLoading: RootStore.assetsLoading + areAssetsLoading: RootStore.overview.balanceLoading assets: RootStore.walletAssetsStore.groupedAccountAssetsModel networkFilters: RootStore.networkFilters addressFilters: RootStore.addressFilters diff --git a/ui/imports/shared/views/AssetsView.qml b/ui/imports/shared/views/AssetsView.qml index a815f8b54a..d6e06c1845 100644 --- a/ui/imports/shared/views/AssetsView.qml +++ b/ui/imports/shared/views/AssetsView.qml @@ -82,7 +82,7 @@ ColumnLayout { root.networkFilters root.addressFilters return root.networkFilters.split(":").includes(model.chainId+"") && - (!!root.addressFilters ? root.addressFilters.toUpperCase() === model.account.toUpperCase() : true) + root.addressFilters.split(":").includes(model.account) } expectedRoles: ["chainId", "account"] } @@ -110,7 +110,10 @@ ColumnLayout { name: "currentCurrencyBalance" expression: { if(!model.communityId) { - return model.currentBalance * model.marketDetails.currencyPrice.amount + if (!!model.marketDetails) { + return model.currentBalance * model.marketDetails.currencyPrice.amount + } + return 0 } else { return model.currentBalance