feat(@wallet): Enable multi network for wallet account

This commit is contained in:
Anthony Laibe 2022-02-10 13:10:56 +01:00 committed by Anthony Laibe
parent b2579230a9
commit 1d83b64fae
9 changed files with 62 additions and 50 deletions

View File

@ -143,9 +143,11 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
statusFoundation.events, statusFoundation.threadpool, result.settingsService, result.networkService
)
result.collectibleService = collectible_service.newService(result.settingsService)
result.walletAccountService = wallet_account_service.newService(statusFoundation.events, result.settingsService,
result.accountsService, result.tokenService)
result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool,
result.walletAccountService = wallet_account_service.newService(
statusFoundation.events, result.settingsService, result.accountsService, result.tokenService,
result.networkService,
)
result.transactionService = transaction_service.newService(statusFoundation.events, statusFoundation.threadpool,
result.walletAccountService, result.ethService, result.networkService, result.settingsService)
result.bookmarkService = bookmark_service.newService()
result.profileService = profile_service.newService()

View File

@ -1,3 +1,4 @@
import tables
import ./controller_interface
import ./io_interface
@ -35,7 +36,9 @@ method init*(self: Controller) =
self.delegate.tokenDetailsWereResolved(args.tokenDetails)
method getTokens*(self: Controller): seq[token_service.TokenDto] =
return self.tokenService.getTokens()
for tokens in self.tokenService.getTokens().values:
for token in tokens:
result.add(token)
method addCustomToken*(self: Controller, chainId: int, address: string, name: string, symbol: string, decimals: int) =
self.tokenService.addCustomToken(chainId, address, name, symbol, decimals)

View File

@ -185,7 +185,7 @@ var NODE_CONFIG* = %* {
},
{
"chainId": 3,
"chainName": "Ropsten",
"chainName": "Ethereum Ropsten",
"rpcUrl": "https://ropsten.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
"blockExplorerUrl": "https://ropsten.etherscan.io/",
"iconUrl": "",
@ -198,7 +198,7 @@ var NODE_CONFIG* = %* {
},
{
"chainId": 4,
"chainName": "Rinkeby",
"chainName": "Ethereum Rinkeby",
"rpcUrl": "https://rinkeby.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
"blockExplorerUrl": "https://rinkeby.etherscan.io/",
"iconUrl": "",
@ -211,7 +211,7 @@ var NODE_CONFIG* = %* {
},
{
"chainId": 5,
"chainName": "Goerli",
"chainName": "Ethereum Goerli",
"rpcUrl": "http://goerli.blockscout.com/",
"blockExplorerUrl": "https://goerli.etherscan.io/",
"iconUrl": "",

View File

@ -420,10 +420,11 @@ QtObject:
var decimals = 18
let allTokens = self.tokenService.getTokens()
for t in allTokens:
if(t.address == sntContract.address):
decimals = t.decimals
break
for tokens in allTokens.values:
for t in tokens:
if(t.address == sntContract.address):
decimals = t.decimals
break
result = ens_utils.hex2Token(balance, decimals)

View File

@ -71,11 +71,6 @@ method getNetwork*(self: Service, chainId: int): NetworkDto =
if chainId == network.chainId:
return network
method getNetwork*(self: Service, chainId: int): NetworkDto =
for network in self.getNetworks():
if chainId == network.chainId:
return network
method getNetwork*(self: Service, networkType: NetworkType): NetworkDto =
for network in self.getNetworks():
if networkType.toChainId() == network.chainId:

View File

@ -93,13 +93,17 @@ QtObject:
error "error: ", errDesription
return
proc getTokens*(self: Service, useCache: bool = true): seq[TokenDto] =
proc getTokens*(self: Service, useCache: bool = true): Table[NetworkDto, seq[TokenDto]] =
if not useCache:
self.init()
for tokens in self.tokens.values:
return self.tokens
proc getVisibleTokens*(self: Service): seq[TokenDto] =
for tokens in self.getTokens().values:
for token in tokens:
result.add(token)
if token.isVisible:
result.add(token)
proc addCustomToken*(self: Service, chainId: int, address: string, name: string, symbol: string, decimals: int) =
# TODO(alaile): use chainId rather than first enabled network

View File

@ -4,6 +4,7 @@ import web3/[ethtypes, conversions]
import ../settings/service_interface as settings_service
import ../accounts/service_interface as accounts_service
import ../token/service as token_service
import ../network/service as network_service
import ../../common/account_constants
import ./service_interface, ./dto
@ -74,16 +75,15 @@ proc fetchAccounts(): seq[WalletAccountDto] =
x => x.toWalletAccountDto()
).filter(a => not a.isChat)
proc fetchEthBalance(accountAddress: string): float64 =
proc fetchNativeChainBalance(network: NetworkDto, accountAddress: string): float64 =
let key = "0x0" & accountAddress
if balanceCache.hasKey(key):
return balanceCache[key]
let ethBalanceResponse = status_go_eth.getEthBalance(accountAddress)
result = parsefloat(hex2Balance(ethBalanceResponse.result.getStr, 18))
let nativeBalanceResponse = status_go_eth.getNativeChainBalance(network.chainId, accountAddress)
result = parsefloat(hex2Balance(nativeBalanceResponse.result.getStr, network.nativeCurrencyDecimals))
balanceCache[key] = result
type AccountSaved = ref object of Args
account: WalletAccountDto
@ -103,46 +103,49 @@ type
settingsService: settings_service.ServiceInterface
accountsService: accounts_service.ServiceInterface
tokenService: token_service.Service
networkService: network_service.Service
accounts: OrderedTable[string, WalletAccountDto]
method delete*(self: Service) =
discard
proc newService*(
events: EventEmitter, settingsService: settings_service.ServiceInterface,
events: EventEmitter,
settingsService: settings_service.ServiceInterface,
accountsService: accounts_service.ServiceInterface,
tokenService: token_service.Service):
Service =
tokenService: token_service.Service,
networkService: network_service.Service,
): Service =
result = Service()
result.events = events
result.settingsService = settingsService
result.accountsService = accountsService
result.tokenService = tokenService
result.networkService = networkService
result.accounts = initOrderedTable[string, WalletAccountDto]()
method getVisibleTokens(self: Service): seq[TokenDto] =
return self.tokenService.getTokens().filter(t => t.isVisible)
method buildTokens(
self: Service,
account: WalletAccountDto,
prices: Table[string, float64],
balances: JsonNode
): seq[WalletTokenDto] =
let balance = fetchEthBalance(account.address)
result = @[WalletTokenDto(
name:"Ethereum",
address: "0x0000000000000000000000000000000000000000",
symbol: "ETH",
decimals: 18,
hasIcon: true,
color: "blue",
isCustom: false,
balance: balance,
currencyBalance: balance * prices["ETH"]
)]
for network in self.networkService.getEnabledNetworks():
let balance = fetchNativeChainBalance(network, account.address)
for token in self.getVisibleTokens():
result.add(WalletTokenDto(
name: network.chainName,
address: "0x0000000000000000000000000000000000000000",
symbol: network.nativeCurrencySymbol,
decimals: network.nativeCurrencyDecimals,
hasIcon: true,
color: "blue",
isCustom: false,
balance: balance,
currencyBalance: balance * prices[network.nativeCurrencySymbol]
))
for token in self.tokenService.getVisibleTokens():
let balance = parsefloat(hex2Balance(balances{token.addressAsString()}.getStr, token.decimals))
result.add(
WalletTokenDto(
@ -163,16 +166,20 @@ method getPrice*(self: Service, crypto: string, fiat: string): float64 =
method fetchPrices(self: Service): Table[string, float64] =
let currency = self.settingsService.getCurrency()
var prices = {"ETH": fetchPrice("ETH", currency)}.toTable
for token in self.getVisibleTokens():
var prices = initTable[string, float64]()
for network in self.networkService.getEnabledNetworks():
prices[network.nativeCurrencySymbol] = fetchPrice(network.nativeCurrencySymbol, currency)
for token in self.tokenService.getVisibleTokens():
prices[token.symbol] = fetchPrice(token.symbol, currency)
return prices
method fetchBalances(self: Service, accounts: seq[string]): JsonNode =
let chainId = self.settingsService.getCurrentNetworkId()
let tokens = self.getVisibleTokens().map(t => t.addressAsString())
return status_go_tokens.getBalances(chainId, accounts, tokens).result
let visibleTokens = self.tokenService.getVisibleTokens()
let tokens = visibleTokens.map(t => t.addressAsString())
let chainIds = visibleTokens.map(t => t.chainId)
return status_go_tokens.getBalances(chainIds, accounts, tokens).result
method refreshBalances(self: Service) =
let prices = self.fetchPrices()

View File

@ -10,7 +10,7 @@ proc getBlockByNumber*(blockNumber: string): RpcResponse[JsonNode] {.raises: [Ex
let payload = %* [blockNumber, false]
return core.callPrivateRPC("eth_getBlockByNumber", payload)
proc getEthBalance*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
proc getNativeChainBalance*(chainId: int, address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [address, "latest"]
return core.callPrivateRPC("eth_getBalance", payload)

View File

@ -7,5 +7,5 @@ export response_type
proc getTokens*(chainId: int): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getTokens", %* [chainId])
proc getBalances*(chainId: int, accounts: seq[string], tokens: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getTokensBalancesForChainIDs", %* [@[chainId], accounts, tokens])
proc getBalances*(chainIds: seq[int], accounts: seq[string], tokens: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getTokensBalancesForChainIDs", %* [chainIds, accounts, tokens])