From 057cdc08da23445c93e662c6f8c1b3fb2c8b2ea5 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 3 Sep 2020 16:00:05 -0400 Subject: [PATCH] feat: update balances when receiving a transaction --- src/app/node/core.nim | 2 +- src/app/wallet/core.nim | 7 ++++++- src/status/libstatus/wallet.nim | 5 +++-- src/status/signals/core.nim | 4 ++-- src/status/signals/types.nim | 5 +++++ src/status/signals/wallet.nim | 14 ++++++++++++++ src/status/wallet.nim | 11 +++++++++-- src/status/wallet/balance_manager.nim | 15 +++++++-------- 8 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 src/status/signals/wallet.nim diff --git a/src/app/node/core.nim b/src/app/node/core.nim index a768e4cd57..847423cc34 100644 --- a/src/app/node/core.nim +++ b/src/app/node/core.nim @@ -25,7 +25,7 @@ proc delete*(self: NodeController) = proc init*(self: NodeController) = self.status.events.on(SignalType.Wallet.event) do(e:Args): - self.view.setLastMessage(WalletSignal(e).content) + self.view.setLastMessage($WalletSignal(e).blockNumber) self.status.events.on(SignalType.DiscoverySummary.event) do(e:Args): self.status.network.peerSummaryChange(DiscoverySummarySignal(e).enodes) diff --git a/src/app/wallet/core.nim b/src/app/wallet/core.nim index 1f62a6e54e..3aca3e6148 100644 --- a/src/app/wallet/core.nim +++ b/src/app/wallet/core.nim @@ -47,4 +47,9 @@ proc init*(self: WalletController) = self.status.events.on(SignalType.Wallet.event) do(e:Args): var data = WalletSignal(e) - debug "New signal received" + if data.eventType == "newblock": + for acc in data.accounts: + self.status.wallet.updateAccount(acc) + # TODO: show notification + # TODO: data.eventType == history, reorg, recent-history-fetching, recent-history-ready: + # see status-react/src/status_im/ethereum/subscriptions.cljs diff --git a/src/status/libstatus/wallet.nim b/src/status/libstatus/wallet.nim index e1284dc65f..840ee3a0f7 100644 --- a/src/status/libstatus/wallet.nim +++ b/src/status/libstatus/wallet.nim @@ -1,10 +1,11 @@ -import json, options, httpclient, json, json_serialization, strformat, stint, strutils, sequtils, chronicles, parseutils, tables -import core, types, utils +import json, json, options, json_serialization, stint, chronicles +import core, types, utils, strutils, strformat from nim_status import validateMnemonic, startWallet import ../wallet/account import ./contracts as contractMethods import eth/common/eth_types import ./types +import ../signals/types as signal_types proc getWalletAccounts*(): seq[WalletAccount] = try: diff --git a/src/status/signals/core.nim b/src/status/signals/core.nim index 68c89105ba..1fe29f9cee 100644 --- a/src/status/signals/core.nim +++ b/src/status/signals/core.nim @@ -1,6 +1,6 @@ import NimQml, eventemitter, tables, json, chronicles, strutils, json_serialization import ../libstatus/types as status_types -import types, messages, discovery, whisperFilter, envelopes, expired +import types, messages, discovery, whisperFilter, envelopes, expired, wallet import ../status logScope: @@ -56,7 +56,7 @@ QtObject: of SignalType.WhisperFilterAdded: signal = whisperFilter.fromEvent(jsonSignal) of SignalType.Wallet: - signal = WalletSignal(content: $jsonSignal) + signal = wallet.fromEvent(jsonSignal) of SignalType.NodeLogin: signal = Json.decode($jsonSignal, NodeSignal) of SignalType.DiscoverySummary: diff --git a/src/status/signals/types.nim b/src/status/signals/types.nim index e74166433e..4f1966dcd2 100644 --- a/src/status/signals/types.nim +++ b/src/status/signals/types.nim @@ -15,6 +15,11 @@ type NodeSignal* = ref object of Signal type WalletSignal* = ref object of Signal content*: string + eventType*: string + blockNumber*: int + accounts*: seq[string] + # newTransactions*: ??? + erc20*: bool type EnvelopeSentSignal* = ref object of Signal messageIds*: seq[string] diff --git a/src/status/signals/wallet.nim b/src/status/signals/wallet.nim new file mode 100644 index 0000000000..a85b2ccaa4 --- /dev/null +++ b/src/status/signals/wallet.nim @@ -0,0 +1,14 @@ +import json +import types + +proc fromEvent*(jsonSignal: JsonNode): Signal = + var signal:WalletSignal = WalletSignal() + if jsonSignal["event"].kind != JNull: + signal.eventType = jsonSignal["event"]["type"].getStr + signal.blockNumber = jsonSignal["event"]["blockNumber"].getInt + signal.erc20 = jsonSignal["event"]["erc20"].getBool + signal.accounts = @[] + for account in jsonSignal["event"]["accounts"]: + signal.accounts.add(account.getStr) + result = signal + \ No newline at end of file diff --git a/src/status/wallet.nim b/src/status/wallet.nim index 91c7073144..383e433d8d 100644 --- a/src/status/wallet.nim +++ b/src/status/wallet.nim @@ -107,12 +107,12 @@ proc generateAccountConfiguredAssets*(self: WalletModel, accountAddress: string) assets.add(existingToken) assets -proc populateAccount*(self: WalletModel, walletAccount: var WalletAccount, balance: string) = +proc populateAccount*(self: WalletModel, walletAccount: var WalletAccount, balance: string, refreshCache: bool = false) = var assets: seq[Asset] = self.generateAccountConfiguredAssets(walletAccount.address) walletAccount.balance = fmt"{balance} {self.defaultCurrency}" walletAccount.assetList = assets walletAccount.realFiatBalance = 0.0 - updateBalance(walletAccount, self.getDefaultCurrency()) + updateBalance(walletAccount, self.getDefaultCurrency(), refreshCache) proc newAccount*(self: WalletModel, name: string, address: string, iconColor: string, balance: string, publicKey: string): WalletAccount = var assets: seq[Asset] = self.generateAccountConfiguredAssets(address) @@ -125,9 +125,16 @@ proc initAccounts*(self: WalletModel) = let accounts = status_wallet.getWalletAccounts() for account in accounts: var acc = WalletAccount(account) + self.populateAccount(acc, "") self.accounts.add(acc) +proc updateAccount*(self: WalletModel, address: string) = + for acc in self.accounts.mitems: + if acc.address == address: + self.populateAccount(acc, "", true) + self.events.emit("accountsUpdated", Args()) + proc getTotalFiatBalance*(self: WalletModel): string = var newBalance = 0.0 fmt"{self.totalBalance:.2f} {self.defaultCurrency}" diff --git a/src/status/wallet/balance_manager.nim b/src/status/wallet/balance_manager.nim index dc68936084..ddca4f7ac3 100644 --- a/src/status/wallet/balance_manager.nim +++ b/src/status/wallet/balance_manager.nim @@ -36,14 +36,13 @@ proc getEthBalance(address: string): string = var balance = status_wallet.getBalance(address) result = status_wallet.hex2token(balance, 18) -proc getBalance*(symbol: string, accountAddress: string, tokenAddress: string): string = +proc getBalance*(symbol: string, accountAddress: string, tokenAddress: string, refreshCache: bool): string = let cacheKey = fmt"{symbol}-{accountAddress}-{tokenAddress}" - if balanceManager.tokenBalances.isCached(cacheKey): + if not refreshCache and balanceManager.tokenBalances.isCached(cacheKey): return balanceManager.tokenBalances.get(cacheKey) if symbol == "ETH": let ethBalance = getEthBalance(accountAddress) - balanceManager.tokenBalances.cacheValue(cacheKey, ethBalance) return ethBalance result = $status_tokens.getTokenBalance(tokenAddress, accountAddress) @@ -59,21 +58,21 @@ proc convertValue*(balance: string, fromCurrency: string, toCurrency: string): f balanceManager.pricePairs.cacheValue(cacheKey, fiat_crypto_price) parseFloat(balance) * parseFloat(fiat_crypto_price) -proc updateBalance*(asset: Asset, currency: string) = - var token_balance = getBalance(asset.symbol, asset.accountAddress, asset.address) +proc updateBalance*(asset: Asset, currency: string, refreshCache: bool) = + var token_balance = getBalance(asset.symbol, asset.accountAddress, asset.address, refreshCache) let fiat_balance = convertValue(token_balance, asset.symbol, currency) asset.value = token_balance asset.fiatBalanceDisplay = fmt"{fiat_balance:.2f} {currency}" asset.fiatBalance = fmt"{fiat_balance:.2f}" -proc updateBalance*(account: WalletAccount, currency: string) = +proc updateBalance*(account: WalletAccount, currency: string, refreshCache: bool = false) = try: - let eth_balance = getBalance("ETH", account.address, "") + let eth_balance = getBalance("ETH", account.address, "", refreshCache) let usd_balance = convertValue(eth_balance, "ETH", currency) var totalAccountBalance = usd_balance account.realFiatBalance = totalAccountBalance account.balance = fmt"{totalAccountBalance:.2f} {currency}" for asset in account.assetList: - updateBalance(asset, currency) + updateBalance(asset, currency, refreshCache) except RpcException: error "Error in updateBalance", message = getCurrentExceptionMsg()