mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-22 11:38:57 +00:00
feat(@wallet): Enable multi network for wallet account
This commit is contained in:
parent
b2579230a9
commit
1d83b64fae
@ -143,8 +143,10 @@ 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.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()
|
||||
|
@ -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)
|
||||
|
@ -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": "",
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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])
|
||||
|
Loading…
x
Reference in New Issue
Block a user