feat: add wallet token integration

This commit is contained in:
Anthony Laibe 2022-11-03 15:11:13 +01:00 committed by Anthony Laibe
parent e3bfdc0f09
commit 0d217c0db0
41 changed files with 218 additions and 1285 deletions

View File

@ -1,18 +1,23 @@
import sugar, sequtils
import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
walletAccountService: wallet_account_service.Service
networkService: network_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
walletAccountService: wallet_account_service.Service
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
): Controller =
result = Controller()
result.delegate = delegate
result.walletAccountService = walletAccountService
result.networkService = networkService
proc delete*(self: Controller) =
discard
@ -28,3 +33,9 @@ proc getIndex*(self: Controller, address: string): int =
method findTokenSymbolByAddress*(self: Controller, address: string): string =
return self.walletAccountService.findTokenSymbolByAddress(address)
proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)

View File

@ -3,6 +3,7 @@ import NimQml, Tables, sequtils
import ../../../../global/global_singleton
import ../../../../core/eventemitter
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
@ -26,13 +27,14 @@ proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
): Module =
result = Module()
result.delegate = delegate
result.events = events
result.currentAccountIndex = 0
result.view = newView(result)
result.controller = newController(result, walletAccountService)
result.controller = newController(result, walletAccountService, networkService)
result.moduleLoaded = false
method delete*(self: Module) =
@ -40,20 +42,23 @@ method delete*(self: Module) =
proc setAssets(self: Module, tokens: seq[WalletTokenDto]) =
var items: seq[Item]
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds()
for t in tokens:
let item = token_item.initItem(
t.name,
t.symbol,
t.totalBalance.balance,
t.totalBalance.currencyBalance,
t.enabledNetworkBalance.balance,
t.enabledNetworkBalance.currencybalance,
t.visible,
toSeq(t.balancesPerChain.values),
t.getBalance(chainIds),
t.getCurrencyBalance(chainIds),
t.getBalance(enabledChainIds),
t.getCurrencyBalance(enabledChainIds),
t.getVisible(enabledChainIds),
t.getBalances(enabledChainIds),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.smartContractAddress,
t.getAddress(),
t.marketCap,
t.highDay,
t.lowDay,
@ -71,7 +76,8 @@ proc setAssets(self: Module, tokens: seq[WalletTokenDto]) =
method switchAccount*(self: Module, accountIndex: int) =
self.currentAccountIndex = accountIndex
let walletAccount = self.controller.getWalletAccount(accountIndex)
self.view.setData(walletAccount)
let enabledChainIds = self.controller.getEnabledChainIds()
self.view.setData(walletAccount, enabledChainIds)
self.setAssets(walletAccount.tokens)
method load*(self: Module) =

View File

@ -143,7 +143,7 @@ QtObject:
proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): string {.slot.} =
return self.assets.getTokenBalanceOnChain(chainId, tokenSymbol)
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto, chainIds: seq[int]) =
self.name = dto.name
self.nameChanged()
self.address = dto.address
@ -158,7 +158,7 @@ proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
self.walletTypeChanged()
self.isChat = dto.isChat
self.isChatChanged()
self.currencyBalance = dto.getCurrencyBalance()
self.currencyBalance = dto.getCurrencyBalance(chainIds)
self.currencyBalanceChanged()
self.emoji = dto.emoji
self.emojiChanged()

View File

@ -46,7 +46,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
result.providerModule = provider_module.newModule(result, events, settingsService, networkService, providerService)
result.bookmarkModule = bookmark_module.newModule(result, events, bookmarkService)
result.dappsModule = dapps_module.newModule(result, dappPermissionsService, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService)
method delete*(self: Module) =
self.view.delete

View File

@ -1,6 +1,8 @@
import sugar, sequtils
import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/accounts/service as accounts_service
import ../../../../../app_service/service/network/service as network_service
import ../../../../global/global_singleton
import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
@ -16,18 +18,21 @@ type
events: EventEmitter
walletAccountService: wallet_account_service.Service
accountsService: accounts_service.Service
networkService: network_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
events: EventEmitter,
walletAccountService: wallet_account_service.Service,
accountsService: accounts_service.Service
accountsService: accounts_service.Service,
networkService: network_service.Service,
): Controller =
result = Controller()
result.delegate = delegate
result.events = events
result.walletAccountService = walletAccountService
result.accountsService = accountsService
result.networkService = networkService
proc delete*(self: Controller) =
discard
@ -100,4 +105,10 @@ proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] =
proc addWalletAccount*(self: Controller, name, address, path, addressAccountIsDerivedFrom, publicKey, keyUid, accountType,
color, emoji: string): string =
return self.walletAccountService.addWalletAccount(name, address, path, addressAccountIsDerivedFrom, publicKey, keyUid,
accountType, color, emoji)
accountType, color, emoji)
proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)

View File

@ -8,6 +8,7 @@ import ../../../../../app_service/common/account_constants
import ../../../../../app_service/service/keycard/service as keycard_service
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/accounts/service as accounts_service
import ../../../../../app_service/service/network/service as network_service
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
import ../../../shared_modules/keycard_popup/module as keycard_shared_module
@ -41,7 +42,8 @@ proc newModule*(
events: EventEmitter,
keycardService: keycard_service.Service,
walletAccountService: wallet_account_service.Service,
accountsService: accounts_service.Service
accountsService: accounts_service.Service,
networkService: network_service.Service
): Module =
result = Module()
result.delegate = delegate
@ -50,7 +52,7 @@ proc newModule*(
result.accountsService = accountsService
result.walletAccountService = walletAccountService
result.view = newView(result)
result.controller = controller.newController(result, events, walletAccountService, accountsService)
result.controller = controller.newController(result, events, walletAccountService, accountsService, networkService)
result.moduleLoaded = false
method delete*(self: Module) =
@ -69,25 +71,25 @@ method refreshWalletAccounts*(self: Module) =
let walletAccounts = self.controller.getWalletAccounts()
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds()
let items = walletAccounts.map(proc (w: WalletAccountDto): item.Item =
let assets = token_model.newModel()
assets.setItems(
w.tokens.map(t => token_item.initItem(
t.name,
t.symbol,
t.totalBalance.balance,
t.totalBalance.currencyBalance,
t.enabledNetworkBalance.balance,
t.enabledNetworkBalance.currencyBalance,
t.visible,
toSeq(t.balancesPerChain.values),
t.getBalance(chainIds),
t.getCurrencyBalance(chainIds),
t.getBalance(enabledChainIds),
t.getCurrencyBalance(enabledChainIds),
t.getVisible(enabledChainIds),
t.getBalances(enabledChainIds),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.smartContractAddress,
t.getAddress(),
t.marketCap,
t.highDay,
t.lowDay,
@ -111,7 +113,7 @@ method refreshWalletAccounts*(self: Module) =
x.walletType,
x.isWallet,
x.isChat,
x.getCurrencyBalance(),
x.getBalance(enabledChainIds),
x.emoji,
x.derivedfrom,
))
@ -126,7 +128,7 @@ method refreshWalletAccounts*(self: Module) =
w.walletType,
w.isWallet,
w.isChat,
w.getCurrencyBalance(),
w.getBalance(enabledChainIds),
assets,
w.emoji,
w.derivedfrom,

View File

@ -29,48 +29,10 @@ proc delete*(self: Controller) =
discard
proc init*(self: Controller) =
self.events.on(SIGNAL_TOKEN_DETAILS_LOADED) do(e:Args):
let args = TokenDetailsLoadedArgs(e)
self.delegate.tokenDetailsWereResolved(args.tokenDetails)
self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args):
self.delegate.refreshTokens()
self.events.on(SIGNAL_TOKEN_HISTORICAL_DATA_LOADED) do(e:Args):
let args = TokenHistoricalDataArgs(e)
self.delegate.tokenHistoricalDataResolved(args.result)
self.events.on(SIGNAL_BALANCE_HISTORY_DATA_READY) do(e:Args):
let args = TokenBalanceHistoryDataArgs(e)
self.delegate.tokenBalanceHistoryDataResolved(args.result)
proc getTokens*(self: Controller): seq[token_service.TokenDto] =
proc compare(x, y: token_service.TokenDto): int =
if x.name < y.name:
return -1
elif x.name > y.name:
return 1
return 0
for tokens in self.tokenService.getTokens().values:
for token in tokens:
result.add(token)
result.sort(compare)
proc addCustomToken*(self: Controller, chainId: int, address: string, name: string, symbol: string, decimals: int): string =
return self.tokenService.addCustomToken(chainId, address, name, symbol, decimals)
proc toggleVisible*(self: Controller, chainId: int, address: string) =
self.walletAccountService.toggleTokenVisible(chainId, address)
proc removeCustomToken*(self: Controller, chainId: int, address: string) =
self.tokenService.removeCustomToken(chainId, address)
proc getTokenDetails*(self: Controller, address: string) =
self.tokenService.getTokenDetails(address)
method findTokenSymbolByAddress*(self: Controller, address: string): string =
return self.walletAccountService.findTokenSymbolByAddress(address)

View File

@ -11,24 +11,6 @@ method load*(self: AccessInterface) {.base.} =
method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method addCustomToken*(self: AccessInterface, chainId: int, address: string, name: string, symbol: string, decimals: int): string {.base.} =
raise newException(ValueError, "No implementation available")
method toggleVisible*(self: AccessInterface, chainId: int, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method removeCustomToken*(self: AccessInterface, chainId: int, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method refreshTokens*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getTokenDetails*(self: AccessInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method tokenDetailsWereResolved*(self: AccessInterface, tokenDetails: string) {.base.} =
raise newException(ValueError, "No implementation available")
method findTokenSymbolByAddress*(self: AccessInterface, address: string): string {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -1,60 +0,0 @@
import strformat
type
Item* = object
name: string
symbol: string
hasIcon: bool
address: string
decimals: int
isCustom: bool
isVisible: bool
chainId: int
proc initItem*(
name, symbol: string, hasIcon: bool, address: string, decimals: int, isCustom: bool, isVisible: bool, chainId: int
): Item =
result.name = name
result.symbol = symbol
result.hasIcon = hasIcon
result.address = address
result.decimals = decimals
result.isCustom = isCustom
result.isVisible = isVisible
result.chainId = chainId
proc `$`*(self: Item): string =
result = fmt"""AllTokensItem(
name: {self.name},
symbol: {self.symbol},
hasIcon: {self.hasIcon},
address: {self.address},
decimals: {self.decimals},
isCustom:{self.isCustom},
isVisible:{self.isVisible},
chainId:{self.chainId}
]"""
proc getName*(self: Item): string =
return self.name
proc getSymbol*(self: Item): string =
return self.symbol
proc getHasIcon*(self: Item): bool =
return self.hasIcon
proc getAddress*(self: Item): string =
return self.address
proc getDecimals*(self: Item): int =
return self.decimals
proc getIsCustom*(self: Item): bool =
return self.isCustom
proc getIsVisible*(self: Item): bool =
return self.isVisible
proc getChainId*(self: Item): int =
return self.chainId

View File

@ -1,92 +0,0 @@
import NimQml, Tables, strutils, strformat
import ./item
type
ModelRole {.pure.} = enum
Name = UserRole + 1,
Symbol
HasIcon
Address
Decimals
IsCustom
IsVisible
ChainId
QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: Model) =
self.QAbstractListModel.setup
proc newModel*(): Model =
new(result, delete)
result.setup
proc `$`*(self: Model): string =
for i in 0 ..< self.items.len:
result &= fmt"""[{i}]:({$self.items[i]})"""
proc countChanged(self: Model) {.signal.}
proc getCount(self: Model): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.Name.int:"name",
ModelRole.Symbol.int:"symbol",
ModelRole.HasIcon.int:"hasIcon",
ModelRole.Address.int:"address",
ModelRole.Decimals.int:"decimals",
ModelRole.IsCustom.int:"isCustom",
ModelRole.IsVisible.int:"isVisible",
ModelRole.ChainId.int:"chainId"
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.Name:
result = newQVariant(item.getName())
of ModelRole.Symbol:
result = newQVariant(item.getSymbol())
of ModelRole.HasIcon:
result = newQVariant(item.getHasIcon())
of ModelRole.Address:
result = newQVariant(item.getAddress())
of ModelRole.Decimals:
result = newQVariant(item.getDecimals())
of ModelRole.IsCustom:
result = newQVariant(item.getIsCustom())
of ModelRole.IsVisible:
result = newQVariant(item.getIsVisible())
of ModelRole.ChainId:
result = newQVariant(item.getChainId())
proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel()
self.items = items
self.endResetModel()
self.countChanged()

View File

@ -1,6 +1,6 @@
import NimQml, sequtils, sugar
import ./io_interface, ./view, ./controller, ./item
import ./io_interface, ./view, ./controller
import ../io_interface as delegate_interface
import ../../../../global/global_singleton
@ -36,34 +36,9 @@ method delete*(self: Module) =
self.view.delete
self.controller.delete
method refreshTokens*(self: Module) =
let tokens = self.controller.getTokens()
self.view.setItems(
tokens.map(t => initItem(
t.name,
t.symbol,
t.hasIcon,
t.addressAsString(),
t.decimals,
t.isCustom,
t.isVisible,
t.chainId,
))
)
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("walletSectionAllTokens", newQVariant(self.view))
# these connections should be part of the controller's init method
self.events.on("token/customTokenAdded") do(e:Args):
self.refreshTokens()
self.events.on("token/visibilityToggled") do(e:Args):
self.refreshTokens()
self.events.on("token/customTokenRemoved") do(e:Args):
self.refreshTokens()
self.controller.init()
self.view.load()
@ -71,25 +46,9 @@ method isLoaded*(self: Module): bool =
return self.moduleLoaded
method viewDidLoad*(self: Module) =
self.refreshTokens()
self.moduleLoaded = true
self.delegate.allTokensModuleDidLoad()
method addCustomToken*(self: Module, chainId: int, address: string, name: string, symbol: string, decimals: int): string =
return self.controller.addCustomToken(chainId, address, name, symbol, decimals)
method toggleVisible*(self: Module, chainId: int, address: string) =
self.controller.toggleVisible(chainId, address)
method removeCustomToken*(self: Module, chainId: int, address: string) =
self.controller.removeCustomToken(chainId, address)
method getTokenDetails*(self: Module, address: string) =
self.controller.getTokenDetails(address)
method tokenDetailsWereResolved*(self: Module, tokenDetails: string) =
self.view.tokenDetailsWereResolved(tokenDetails)
method findTokenSymbolByAddress*(self: Module, address: string): string =
return self.controller.findTokenSymbolByAddress(address)

View File

@ -1,80 +1,23 @@
import NimQml, sequtils, sugar, strutils
import ./model
import ./item
import ./io_interface
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
default: Model
custom: Model
all: Model
proc delete*(self: View) =
self.default.delete
self.custom.delete
self.all.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.QObject.setup
result.delegate = delegate
result.default = newModel()
result.custom = newModel()
result.all = newModel()
proc load*(self: View) =
self.delegate.viewDidLoad()
proc allChanged*(self: View) {.signal.}
proc getAll(self: View): QVariant {.slot.} =
return newQVariant(self.all)
QtProperty[QVariant] all:
read = getAll
notify = allChanged
proc defaultChanged*(self: View) {.signal.}
proc getDefault(self: View): QVariant {.slot.} =
return newQVariant(self.default)
QtProperty[QVariant] default:
read = getDefault
notify = defaultChanged
proc customChanged*(self: View) {.signal.}
proc getCustom(self: View): QVariant {.slot.} =
return newQVariant(self.custom)
QtProperty[QVariant] custom:
read = getCustom
notify = customChanged
proc setItems*(self: View, items: seq[Item]) =
self.all.setItems(items)
self.custom.setItems(items.filter(i => i.getIsCustom()))
self.default.setItems(items.filter(i => not i.getIsCustom()))
proc addCustomToken(self: View, chainId: int, address: string, name: string, symbol: string, decimals: string): string {.slot.} =
return self.delegate.addCustomToken(chainId, address, name, symbol, parseInt(decimals))
proc toggleVisible(self: View, chainId: int, address: string) {.slot.} =
self.delegate.toggleVisible(chainId, address)
proc removeCustomToken(self: View, chainId: int, address: string) {.slot.} =
self.delegate.removeCustomToken(chainId, address)
proc tokenDetailsWereResolved*(self: View, tokenDetails: string) {.signal.}
proc getTokenDetails*(self: View, address: string) {.slot.} =
self.delegate.getTokenDetails(address)
proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} =
return self.delegate.findTokenSymbolByAddress(address)

View File

@ -1,26 +1,22 @@
import io_interface
import ../../../../app_service/service/settings/service as settings_service
import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/network/service as network_service
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
settingsService: settings_service.Service
walletAccountService: wallet_account_service.Service
networkService: network_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
settingsService: settings_service.Service,
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
): Controller =
result = Controller()
result.delegate = delegate
result.settingsService = settingsService
result.walletAccountService = walletAccountService
result.networkService = networkService
proc delete*(self: Controller) =
discard
@ -38,7 +34,7 @@ proc isMnemonicBackedUp*(self: Controller): bool =
return self.settingsService.getMnemonic().len > 0
proc getCurrencyBalance*(self: Controller): float64 =
return self.walletAccountService.getCurrencyBalance()
return self.walletAccountService.getTotalCurrencyBalance()
proc updateCurrency*(self: Controller, currency: string) =
self.walletAccountService.updateCurrency(currency)

View File

@ -1,19 +1,24 @@
import sugar, sequtils
import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
walletAccountService: wallet_account_service.Service
networkService: network_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
walletAccountService: wallet_account_service.Service
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
): Controller =
result = Controller()
result.delegate = delegate
result.walletAccountService = walletAccountService
result.networkService = networkService
proc delete*(self: Controller) =
discard
@ -29,3 +34,9 @@ proc update*(self: Controller, address: string, accountName: string, color: stri
method findTokenSymbolByAddress*(self: Controller, address: string): string =
return self.walletAccountService.findTokenSymbolByAddress(address)
proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)

View File

@ -3,6 +3,7 @@ import NimQml, Tables, sequtils
import ../../../../global/global_singleton
import ../../../../core/eventemitter
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
@ -26,13 +27,14 @@ proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
walletAccountService: wallet_account_service.Service,
networkService: network_service.Service,
): Module =
result = Module()
result.delegate = delegate
result.events = events
result.currentAccountIndex = 0
result.view = newView(result)
result.controller = newController(result, walletAccountService)
result.controller = newController(result, walletAccountService, networkService)
result.moduleLoaded = false
method delete*(self: Module) =
@ -70,21 +72,24 @@ method viewDidLoad*(self: Module) =
proc setAssetsAndBalance(self: Module, tokens: seq[WalletTokenDto]) =
var totalCurrencyBalanceForAllAssets = 0.0
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds()
var items: seq[Item]
for t in tokens:
let item = token_item.initItem(
t.name,
t.symbol,
t.totalBalance.balance,
t.totalBalance.currencyBalance,
t.enabledNetworkBalance.balance,
t.enabledNetworkBalance.currencybalance,
t.visible,
toSeq(t.balancesPerChain.values),
t.getBalance(chainIds),
t.getCurrencyBalance(chainIds),
t.getBalance(enabledChainIds),
t.getCurrencyBalance(enabledChainIds),
t.getVisible(enabledChainIds),
t.getBalances(enabledChainIds),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.smartContractAddress,
t.getAddress(),
t.marketCap,
t.highDay,
t.lowDay,
@ -96,17 +101,18 @@ proc setAssetsAndBalance(self: Module, tokens: seq[WalletTokenDto]) =
t.decimals,
)
items.add(item)
totalCurrencyBalanceForAllAssets += t.enabledNetworkBalance.currencybalance
totalCurrencyBalanceForAllAssets += t.getCurrencyBalance(enabledChainIds)
self.view.getAssetsModel().setItems(items)
self.view.setCurrencyBalance(totalCurrencyBalanceForAllAssets)
method switchAccount*(self: Module, accountIndex: int) =
self.currentAccountIndex = accountIndex
let enabledChainIds = self.controller.getEnabledChainIds()
let walletAccount = self.controller.getWalletAccount(accountIndex)
# can safely do this as the account will always contain atleast one account
self.view.setDefaultWalletAccount(self.controller.getWalletAccount(0))
self.view.setData(walletAccount)
self.view.setData(walletAccount, enabledChainIds)
self.setAssetsAndBalance(walletAccount.tokens)
method update*(self: Module, address: string, accountName: string, color: string, emoji: string) =

View File

@ -166,7 +166,7 @@ QtObject:
proc setDefaultWalletAccount*(self: View, default: wallet_account_service.WalletAccountDto) =
self.defaultAccount = default
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto, chainIds: seq[int]) =
if(self.name != dto.name):
self.name = dto.name
self.nameChanged()
@ -214,7 +214,7 @@ QtObject:
x.walletType,
x.isWallet,
x.isChat,
x.getCurrencyBalance(),
x.getCurrencyBalance(chainIds),
x.emoji,
x.derivedfrom
))

View File

@ -61,13 +61,13 @@ proc newModule*(
result.delegate = delegate
result.events = events
result.moduleLoaded = false
result.controller = newController(result, settingsService, walletAccountService, networkService)
result.controller = newController(result, settingsService, walletAccountService)
result.view = newView(result)
result.accountsModule = accounts_module.newModule(result, events, keycardService, walletAccountService, accountsService)
result.accountsModule = accounts_module.newModule(result, events, keycardService, walletAccountService, accountsService, networkService)
result.allTokensModule = all_tokens_module.newModule(result, events, tokenService, walletAccountService)
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService)
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService, networkService)
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)

View File

@ -7,8 +7,6 @@ type
ChainId = UserRole + 1,
Address
Balance
CurrencyBalance
Enabled
QtObject:
type
@ -47,8 +45,6 @@ QtObject:
ModelRole.ChainId.int:"chainId",
ModelRole.Address.int:"address",
ModelRole.Balance.int:"balance",
ModelRole.CurrencyBalance.int:"currencyBalance",
ModelRole.Enabled.int:"enabled",
}.toTable
method data(self: BalanceModel, index: QModelIndex, role: int): QVariant =
@ -67,11 +63,7 @@ QtObject:
of ModelRole.Address:
result = newQVariant(item.address)
of ModelRole.Balance:
result = newQVariant(item.balance)
of ModelRole.CurrencyBalance:
result = newQVariant(item.currencyBalance)
of ModelRole.Enabled:
result = newQVariant(item.enabled)
result = newQVariant($item.balance)
proc rowData(self: BalanceModel, index: int, column: string): string {.slot.} =
if (index >= self.items.len):
@ -81,8 +73,6 @@ QtObject:
of "chainId": result = $item.chainId
of "address": result = $item.address
of "balance": result = $item.balance
of "currencyBalance": result = $item.currencyBalance
of "enabled": result = $item.enabled
proc setItems*(self: BalanceModel, items: seq[BalanceDto]) =
self.beginResetModel()

View File

@ -16,7 +16,7 @@ type
description: string
assetWebsiteUrl: string
builtOn: string
smartContractAddress: string
address: string
marketCap: string
highDay: string
lowDay: string
@ -38,7 +38,7 @@ proc initItem*(
description: string,
assetWebsiteUrl: string,
builtOn: string,
smartContractAddress: string,
address: string,
marketCap: string,
highDay: string,
lowDay: string,
@ -61,7 +61,7 @@ proc initItem*(
result.description = description
result.assetWebsiteUrl = assetWebsiteUrl
result.builtOn = builtOn
result.smartContractAddress = smartContractAddress
result.address = address
result.marketCap = marketCap
result.highDay = highDay
result.lowDay = lowDay
@ -84,7 +84,7 @@ proc `$`*(self: Item): string =
description: {self.description},
assetWebsiteUrl: {self.assetWebsiteUrl}
builtOn: {self.builtOn}
smartContractAddress: {self.smartContractAddress}
address: {self.address}
marketCap: {self.marketCap},
highDay: {self.highDay},
lowDay: {self.lowDay},
@ -129,8 +129,8 @@ proc getAssetWebsiteUrl*(self: Item): string =
proc getBuiltOn*(self: Item): string =
return self.builtOn
proc getSmartContractAddress*(self: Item): string =
return self.smartContractAddress
proc getAddress*(self: Item): string =
return self.address
proc getMarketCap*(self: Item): string =
return self.marketCap

View File

@ -15,7 +15,7 @@ type
Description
AssetWebsiteUrl
BuiltOn
SmartContractAddress
Address
MarketCap
HighDay
LowDay
@ -71,7 +71,7 @@ QtObject:
ModelRole.Description.int:"description",
ModelRole.AssetWebsiteUrl.int:"assetWebsiteUrl",
ModelRole.BuiltOn.int:"builtOn",
ModelRole.SmartContractAddress.int:"smartContractAddress",
ModelRole.Address.int:"address",
ModelRole.MarketCap.int:"marketCap",
ModelRole.HighDay.int:"highDay",
ModelRole.LowDay.int:"lowDay",
@ -116,8 +116,8 @@ QtObject:
result = newQVariant(item.getAssetWebsiteUrl())
of ModelRole.BuiltOn:
result = newQVariant(item.getBuiltOn())
of ModelRole.SmartContractAddress:
result = newQVariant(item.getSmartContractAddress())
of ModelRole.Address:
result = newQVariant(item.getAddress())
of ModelRole.MarketCap:
result = newQVariant(item.getMarketCap())
of ModelRole.HighDay:
@ -152,7 +152,7 @@ QtObject:
of "description": result = $item.getDescription()
of "assetWebsiteUrl": result = $item.getAssetWebsiteUrl()
of "builtOn": result = $item.getBuiltOn()
of "smartContractAddress": result = $item.getSmartContractAddress()
of "Address": result = $item.getAddress()
of "marketCap": result = $item.getMarketCap()
of "highDay": result = $item.getHighDay()
of "lowDay": result = $item.getLowDay()

View File

@ -464,10 +464,10 @@ proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAcco
return
return self.walletAccountService.fetchAccounts()
proc getBalanceForAddress*(self: Controller, address: string): float64 =
proc getCurrencyBalanceForAddress*(self: Controller, address: string): float64 =
if not serviceApplicable(self.walletAccountService):
return
return self.walletAccountService.fetchBalanceForAddress(address)
return self.walletAccountService.getCurrencyBalanceForAddress(address)
proc addMigratedKeyPair*(self: Controller, keyPair: KeyPairDto) =
if not serviceApplicable(self.walletAccountService):

View File

@ -470,7 +470,7 @@ method setKeyPairStoredOnKeycard*[T](self: Module[T], cardMetadata: CardMetadata
for wa in cardMetadata.walletAccounts:
if self.updateKeyPairItemIfDataAreKnown(wa.address, item):
continue
let balance = self.controller.getBalanceForAddress(wa.address)
let balance = self.controller.getCurrencyBalanceForAddress(wa.address)
knownKeyPair = false
item.addAccount(name = "", wa.path, wa.address, emoji = "", color = self.generateRandomColor(), icon = "wallet", balance)
self.view.setKeyPairStoredOnKeycardIsKnown(knownKeyPair)

View File

@ -11,35 +11,6 @@ import ./dto
const DAYS_IN_WEEK = 7
const HOURS_IN_DAY = 24
type
GetTokenDetailsTaskArg = ref object of QObjectTaskArg
chainIds: seq[int]
address: string
const getTokenDetailsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[GetTokenDetailsTaskArg](argEncoded)
for chainId in arg.chainIds:
try:
let response = backend.discoverToken(chainId, arg.address).result
let output = %* {
"address": arg.address,
"name": response{"name"}.getStr,
"symbol": response{"symbol"}.getStr,
"decimals": response{"decimals"}.getInt
}
arg.finish(output)
return
except Exception as e:
continue
let output = %* {
"address": arg.address,
"error": "Is this an ERC-20 or ERC-721 contract?",
}
arg.finish(output)
type
GetTokenHistoricalDataTaskArg = ref object of QObjectTaskArg
symbol: string

View File

@ -62,18 +62,7 @@ proc newTokenDto*(
symbol: symbol,
decimals: decimals,
hasIcon: hasIcon,
isCustom: isCustom,
description: description,
assetWebsiteUrl: assetWebsiteUrl,
builtOn: builtOn,
smartContractAddress: smartContractAddress,
marketCap: marketCap,
highDay: highDay,
lowDay: lowDay,
changePctHour: changePctHour,
changePctDay: changePctDay,
changePct24hour: changePct24hour,
change24hour: change24hour,
isCustom: isCustom
)
proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCustom: bool = true): TokenDto =
@ -87,18 +76,6 @@ proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCu
discard jsonObj.getProp("symbol", result.symbol)
discard jsonObj.getProp("decimals", result.decimals)
discard jsonObj.getProp("color", result.color)
discard jsonObj.getProp("description", result.description)
discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl)
discard jsonObj.getProp("builtOn", result.builtOn)
discard jsonObj.getProp("smartContractAddress", result.smartContractAddress)
discard jsonObj.getProp("marketCap", result.marketCap)
discard jsonObj.getProp("highDay", result.highDay)
discard jsonObj.getProp("lowDay", result.lowDay)
discard jsonObj.getProp("changePctHour", result.changePctHour)
discard jsonObj.getProp("changePctDay", result.changePctDay)
discard jsonObj.getProp("changePct24hour", result.changePct24hour)
discard jsonObj.getProp("change24hour", result.change24hour)
result.isVisible = isVisible
proc addressAsString*(self: TokenDto): string =

View File

@ -19,27 +19,9 @@ logScope:
include async_tasks
# Signals which may be emitted by this service:
const SIGNAL_TOKEN_DETAILS_LOADED* = "tokenDetailsLoaded"
const SIGNAL_TOKEN_LIST_RELOADED* = "tokenListReloaded"
const SIGNAL_TOKEN_HISTORICAL_DATA_LOADED* = "tokenHistoricalDataLoaded"
const SIGNAL_BALANCE_HISTORY_DATA_READY* = "tokenBalanceHistoryDataReady"
type
TokenDetailsLoadedArgs* = ref object of Args
tokenDetails*: string
type
CustomTokenAdded* = ref object of Args
token*: TokenDto
type
CustomTokenRemoved* = ref object of Args
token*: TokenDto
type
VisibilityToggled* = ref object of Args
token*: TokenDto
type
TokenHistoricalDataArgs* = ref object of Args
result*: string
@ -72,22 +54,27 @@ QtObject:
proc init*(self: Service) =
try:
self.tokens = initTable[NetworkDto, seq[TokenDto]]()
let networks = self.networkService.getNetworks()
let chainIds = networks.map(n => n.chainId)
let responseCustomTokens = backend.getCustomTokens()
for network in networks:
var found = false
for n in self.tokens.keys:
if n.chainId == network.chainId:
found = true
break
if found:
continue
echo network.chainId
let responseTokens = backend.getTokens(network.chainId)
let default_tokens = map(
responseTokens.result.getElems(),
proc(x: JsonNode): TokenDto = x.toTokenDto(network.enabled, hasIcon=true, isCustom=false)
)
self.tokens[network] = concat(
default_tokens,
map(responseCustomTokens.result.getElems(), proc(x: JsonNode): TokenDto = x.toTokenDto(network.enabled))
).filter(
self.tokens[network] = default_tokens.filter(
proc(x: TokenDto): bool = x.chainId == network.chainId
)
@ -99,11 +86,6 @@ QtObject:
proc getTokens*(self: Service): Table[NetworkDto, seq[TokenDto]] =
return self.tokens
proc findTokenByName*(self: Service, network: NetworkDto, name: string): TokenDto =
for token in self.tokens[network]:
if token.name == name:
return token
proc findTokenBySymbol*(self: Service, network: NetworkDto, symbol: string): TokenDto =
try:
for token in self.tokens[network]:
@ -117,7 +99,7 @@ QtObject:
if token.address == address:
return token
proc findTokenSymbolByAddressInAllNetworks*(self: Service, address: string): string =
proc findTokenSymbolByAddress*(self: Service, address: string): string =
if address.isEmptyOrWhitespace:
return ""
@ -135,74 +117,6 @@ QtObject:
return token.symbol
return ""
proc addCustomToken*(self: Service, chainId: int, address: string, name: string, symbol: string, decimals: int): string =
# TODO(alaile): use chainId rather than first enabled network
let networkWIP = self.networkService.getNetworks()[0]
let foundToken = self.findTokenByAddress(networkWIP, parseAddress(address))
if not foundToken.isNil:
return "token already exists"
let backendToken = backend.Token(
name: name, chainId: networkWIP.chainId, address: address, symbol: symbol, decimals: decimals, color: ""
)
discard backend.addCustomToken(backendToken)
let token = newTokenDto(
name,
networkWIP.chainId,
fromHex(Address, address),
symbol,
decimals,
false,
true
)
let network = self.networkService.getNetwork(networkWIP.chainId)
self.tokens[network].add(token)
self.events.emit("token/customTokenAdded", CustomTokenAdded(token: token))
proc toggleVisible*(self: Service, chainId: int, address: string) =
discard backend.toggleVisibleToken(chainId, address)
let network = self.networkService.getNetwork(chainId)
var tokenChanged = self.tokens[network][0]
for token in self.tokens[network]:
if token.addressAsString() == address:
token.isVisible = not token.isVisible
tokenChanged = token
break
self.events.emit("token/visibilityToggled", VisibilityToggled(token: tokenChanged))
proc removeCustomToken*(self: Service, chainId: int, address: string) =
let network = self.networkService.getNetwork(chainId)
discard backend.deleteCustomTokenByChainID(chainId, address)
var index = -1
for idx, token in self.tokens[network].pairs():
if $token.address == address:
index = idx
break
let tokenRemoved = self.tokens[network][index]
self.tokens[network].del(index)
self.events.emit("token/customTokenRemoved", CustomTokenRemoved(token: tokenRemoved))
proc tokenDetailsResolved*(self: Service, tokenDetails: string) {.slot.} =
self.events.emit(SIGNAL_TOKEN_DETAILS_LOADED, TokenDetailsLoadedArgs(
tokenDetails: tokenDetails
))
proc getTokenDetails*(self: Service, address: string) =
let chainIds = self.networkService.getNetworks().map(n => n.chainId)
let arg = GetTokenDetailsTaskArg(
tptr: cast[ByteAddress](getTokenDetailsTask),
vptr: cast[ByteAddress](self.vptr),
slot: "tokenDetailsResolved",
chainIds: chainIds,
address: address
)
self.threadpool.start(arg)
proc tokenHistoricalDataResolved*(self: Service, response: string) {.slot.} =
let responseObj = response.parseJson
if (responseObj.kind != JObject):

View File

@ -109,339 +109,12 @@ const timerTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
type
BuildTokensTaskArg = ref object of QObjectTaskArg
walletAddresses: seq[string]
currency: string
networks: seq[NetworkDto]
proc getCustomTokens(): seq[TokenDto] =
try:
let responseCustomTokens = backend.getCustomTokens()
result = map(responseCustomTokens.result.getElems(), proc(x: JsonNode): TokenDto = x.toTokenDto(true))
except Exception as e:
error "error fetching custom tokens: ", message = e.msg
proc getTokensForChainId(network: NetworkDto): seq[TokenDto] =
try:
let responseTokens = backend.getTokens(network.chainId)
let defaultTokens = map(
responseTokens.result.getElems(),
proc(x: JsonNode): TokenDto = x.toTokenDto(network.enabled, hasIcon=true, isCustom=false)
)
result.add(defaultTokens)
except Exception as e:
error "error fetching tokens: ", message = e.msg, chainId=network.chainId
proc isNetworkEnabledForChainId(networks: seq[NetworkDto], chainId: int): bool =
for network in networks:
if network.chainId == chainId:
return network.enabled
return false
proc prepareSymbols(networkSymbols: seq[string], allTokens: seq[TokenDto]): seq[seq[string]] =
# we have to use up to 300 characters in a single request when we're fetching prices
let charsMaxLenght = 300
result.add(@[])
var networkSymbolsIndex = 0
var tokenSymbolsIndex = 0
while networkSymbolsIndex < networkSymbols.len or tokenSymbolsIndex < allTokens.len:
var currentCharsLen = 0
var reachTheEnd = false
while networkSymbolsIndex < networkSymbols.len:
if(currentCharsLen + networkSymbols[networkSymbolsIndex].len >= charsMaxLenght):
reachTheEnd = true
result.add(@[])
break
else:
currentCharsLen += networkSymbols[networkSymbolsIndex].len + 1 # we add one for ','
result[result.len - 1].add(networkSymbols[networkSymbolsIndex])
networkSymbolsIndex.inc
while not reachTheEnd and tokenSymbolsIndex < allTokens.len:
if(currentCharsLen + allTokens[tokenSymbolsIndex].symbol.len >= charsMaxLenght):
reachTheEnd = true
result.add(@[])
break
else:
currentCharsLen += allTokens[tokenSymbolsIndex].symbol.len + 1 # we add one for ','
result[result.len - 1].add(allTokens[tokenSymbolsIndex].symbol)
tokenSymbolsIndex.inc
proc fetchNativeChainBalance(chainId: int, nativeCurrencyDecimals: int, accountAddress: string): float64 =
result = 0.0
try:
let nativeBalanceResponse = status_go_eth.getNativeChainBalance(chainId, accountAddress)
result = parsefloat(hex2Balance(nativeBalanceResponse.result.getStr, nativeCurrencyDecimals))
except Exception as e:
error "error getting balance", message = e.msg
proc fetchPrices(networkSymbols: seq[string], allTokens: seq[TokenDto], currency: string): Table[string, float] =
let allSymbols = prepareSymbols(networkSymbols, allTokens)
for symbols in allSymbols:
if symbols.len == 0:
continue
try:
let response = backend.fetchPrices(symbols, currency)
for (symbol, value) in response.result.pairs:
result[symbol] = value.getFloat
except Exception as e:
error "error fetching prices: ", message = e.msg
proc getMarketValues(networkSymbols: seq[string], allTokens: seq[TokenDto], currency: string): Table[string, Table[string, string]] =
let allSymbols = prepareSymbols(networkSymbols, allTokens)
for symbols in allSymbols:
if symbols.len == 0:
continue
try:
let response = backend.fetchMarketValues(symbols, currency)
for (symbol, marketValue) in response.result.pairs:
var marketValues: Table[string, string] = initTable[string, string]()
for (key, value) in marketValue.pairs:
marketValues[key] = value.getStr()
result[symbol] = marketValues
except Exception as e:
error "error fetching markey values: ", message = e.msg
proc getTokenDetails(networkSymbols: seq[string], allTokens: seq[TokenDto]): Table[string, Table[string, string]] =
let allSymbols = prepareSymbols(networkSymbols, allTokens)
for symbols in allSymbols:
if symbols.len == 0:
continue
try:
let response = backend.fetchTokenDetails(symbols)
for (symbol, tokenDetail) in response.result.pairs:
var tokenDetails: Table[string, string] = initTable[string, string]()
for (key, value) in tokenDetail.pairs:
tokenDetails[key] = value.getStr()
result[symbol] = tokenDetails
except Exception as e:
error "error fetching markey values: ", message = e.msg
proc getTokensBalances(walletAddresses: seq[string], allTokens: seq[TokenDto]): JsonNode =
try:
result = newJObject()
let tokensAddresses = allTokens.map(t => t.addressAsString())
# We need to check, we should use `chainIdsFromSettings` instead `chainIds` deduced from the allTokens list?
let chainIds = deduplicate(allTokens.map(t => t.chainId))
let tokensBalancesResponse = backend.getTokensBalancesForChainIDs(chainIds, walletAddresses, tokensAddresses)
result = tokensBalancesResponse.result
except Exception as e:
error "error fetching tokens balances: ", message = e.msg
proc groupNetworksBySymbol(networks: seq[NetworkDto]): Table[string, seq[NetworkDto]] =
for network in networks:
if not result.hasKey(network.nativeCurrencySymbol):
result[network.nativeCurrencySymbol] = @[]
result[network.nativeCurrencySymbol].add(network)
proc getNetworkByCurrencySymbol(networks: seq[NetworkDto], networkNativeCurrencySymbol: string): NetworkDto =
for network in networks:
if network.nativeCurrencySymbol != networkNativeCurrencySymbol:
continue
return network
proc groupTokensBySymbol(tokens: seq[TokenDto]): Table[string, seq[TokenDto]] =
for token in tokens:
if not result.hasKey(token.symbol):
result[token.symbol] = @[]
result[token.symbol].add(token)
proc getTokenForSymbol(tokens: seq[TokenDto], symbol: string): TokenDto =
for token in tokens:
if token.symbol != symbol:
continue
return token
discard
const prepareTokensTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[BuildTokensTaskArg](argEncoded)
var networkSymbols: seq[string]
var allTokens: seq[TokenDto]
for network in arg.networks:
networkSymbols.add(network.nativeCurrencySymbol)
allTokens.add(getTokensForChainId(network))
allTokens.add(getCustomTokens())
allTokens = deduplicate(allTokens)
var prices = fetchPrices(networkSymbols, allTokens, arg.currency)
var marketValues = getMarketValues(networkSymbols, allTokens, arg.currency)
var tokenDetails = getTokenDetails(networkSymbols, allTokens)
let tokenBalances = getTokensBalances(arg.walletAddresses, allTokens)
var builtTokensPerAccount = %*{ }
for address in arg.walletAddresses:
var builtTokens: seq[WalletTokenDto]
let groupedNetworks = groupNetworksBySymbol(arg.networks)
var enabledNetworkBalance = BalanceDto(
balance: 0.0,
currencyBalance: 0.0
)
for networkNativeCurrencySymbol, networks in groupedNetworks.pairs:
# Reset
enabledNetworkBalance = BalanceDto(
balance: 0.0,
currencyBalance: 0.0
)
var balancesPerChain = initTable[int, BalanceDto]()
for network in networks:
let chainBalance = fetchNativeChainBalance(network.chainId, network.nativeCurrencyDecimals, address)
balancesPerChain[network.chainId] = BalanceDto(
balance: chainBalance,
currencyBalance: chainBalance * prices[network.nativeCurrencySymbol],
chainId: network.chainId,
address: "0x0000000000000000000000000000000000000000",
enabled: network.enabled,
)
if network.enabled:
enabledNetworkBalance.balance += balancesPerChain[network.chainId].balance
enabledNetworkBalance.currencyBalance += balancesPerChain[network.chainId].currencyBalance
let networkDto = getNetworkByCurrencySymbol(arg.networks, networkNativeCurrencySymbol)
var totalTokenBalance: BalanceDto
totalTokenBalance.balance = toSeq(balancesPerChain.values).map(x => x.balance).foldl(a + b)
totalTokenBalance.currencyBalance = totalTokenBalance.balance * prices[networkDto.nativeCurrencySymbol]
var marketCap: string = ""
var highDay: string = ""
var lowDay: string = ""
var changePctHour: string = ""
var changePctDay: string = ""
var changePct24hour: string = ""
var change24hour: string = ""
if(marketValues.hasKey(networkDto.nativeCurrencySymbol)):
marketCap = marketValues[networkDto.nativeCurrencySymbol]["MKTCAP"]
highDay = marketValues[networkDto.nativeCurrencySymbol]["HIGHDAY"]
lowDay = marketValues[networkDto.nativeCurrencySymbol]["LOWDAY"]
changePctHour = marketValues[networkDto.nativeCurrencySymbol]["CHANGEPCTHOUR"]
changePctDay = marketValues[networkDto.nativeCurrencySymbol]["CHANGEPCTDAY"]
changePct24hour = marketValues[networkDto.nativeCurrencySymbol]["CHANGEPCT24HOUR"]
change24hour = marketValues[networkDto.nativeCurrencySymbol]["CHANGE24HOUR"]
builtTokens.add(WalletTokenDto(
name: networkDto.nativeCurrencyName,
symbol: networkDto.nativeCurrencySymbol,
decimals: networkDto.nativeCurrencyDecimals,
hasIcon: true,
color: "blue",
isCustom: false,
totalBalance: totalTokenBalance,
enabledNetworkBalance: enabledNetworkBalance,
balancesPerChain: balancesPerChain,
visible: networkDto.enabled,
description: "Ethereum is a decentralized platform that runs smart contracts (applications that run exactly as programmed without any possibility of downtime, censorship, fraud or third party interference). In the Ethereum protocol and blockchain, there is a price for each operation. In order to have anything transferred or executed by the network, you have to consume or burn Gas. Ethereums native cryptocurrency is Ether (ETH) and it is used to pay for computation time and transaction fees.The introductory whitepaper was originally published in 2013 by Vitalik Buterin, the founder of Ethereum, the project was crowdfunded during August 2014 by fans all around the world and launched in 2015. Ethereum is developed and maintained by ETHDEV with contributions from minds across the globe. There is an Ecosystem Support Program which is a branch of the Ethereum Foundation focused on supporting projects and entities within the greater Ethereum community to promote the success and growth of the ecosystem. Multiple startups work with the Ethereum blockchain covering areas in: DeFi, NFTs, Ethereum Name Service, Wallets, Scaling, etc.The launch of Ethereum is a process divided into 4 main phases: Frontier, Homestead, Metropolis and Serenity.Ethereum 2.0, also known as Serenity, is the final phase of Ethereum, it aims to solve the decentralized scaling challenge. A naive way to solve Ethereum&#39;s problems would be to make it more centralized. But decentralization is too important, as it gives Ethereum censorship resistance, openness, data privacy and near-unbreakable security.The Eth2 upgrades will make Ethereum scalable, secure, and decentralized. Sharding will make Ethereum more scalable by increasing transactions per second while decreasing the power needed to run a node and validate the chain. The beacon chain will make Ethereum secure by coordinating validators across shards. And staking will lower the barrier to participation, creating a larger more decentralized network.The beacon chain will also introduce proof-of-stake to Ethereum. Ethereum is moving to the proof-of-stake (PoS) consensus mechanism from proof-of-work (PoW). This was always the plan as it&#39;s a key part of the community&#39;s strategy to scale Ethereum via the Eth2 upgrades. However, getting PoS right is a big technical challenge and not as straightforward as using PoW to reach consensus across the networkKeep up with Ethereum upgradesFor ETH holders and Dapp users, this has no impact whatsoever, however, for users wishing to get involved, there are ways to participate in Ethereum and future Eth2-related efforts. Get involved in Eth 2.0Blockchain data provided by: Etherchain (Main Source), Blockchair (Backup), and Etherscan (Total Supply only).",
assetWebsiteUrl: "https://www.ethereum.org/",
builtOn: "",
smartContractAddress: "",
marketCap: marketCap,
highDay: highDay,
lowDay: lowDay,
changePctHour: changePctHour,
changePctDay: changePctDay,
changePct24hour: changePct24hour,
change24hour: change24hour,
currencyPrice: prices[networkDto.nativeCurrencySymbol],
)
)
let groupedTokens = groupTokensBySymbol(allTokens)
for symbol, tokens in groupedTokens.pairs:
# Reset
enabledNetworkBalance = BalanceDto(
balance: 0.0,
currencyBalance: 0.0
)
var balancesPerChain = initTable[int, BalanceDto]()
var visible = false
for token in tokens:
let balanceForToken = tokenBalances{address}{token.addressAsString()}.getStr
let chainBalanceForToken = parsefloat(hex2Balance(balanceForToken, token.decimals))
var enabled = false
for network in arg.networks:
if network.chainId == token.chainId:
enabled = true
balancesPerChain[token.chainId] = BalanceDto(
balance: chainBalanceForToken,
currencyBalance: chainBalanceForToken * prices[token.symbol],
chainId: token.chainId,
address: $token.address,
enabled: enabled,
)
if isNetworkEnabledForChainId(arg.networks, token.chainId):
visible = true
enabledNetworkBalance.balance += balancesPerChain[token.chainId].balance
enabledNetworkBalance.currencyBalance += balancesPerChain[token.chainId].currencyBalance
let tokenDto = getTokenForSymbol(allTokens, symbol)
var totalTokenBalance: BalanceDto
totalTokenBalance.balance = toSeq(balancesPerChain.values).map(x => x.balance).foldl(a + b)
totalTokenBalance.currencyBalance = totalTokenBalance.balance * prices[tokenDto.symbol]
var marketCap: string = ""
var highDay: string = ""
var lowDay: string = ""
var changePctHour: string = ""
var changePctDay: string = ""
var changePct24hour: string = ""
var change24hour: string = ""
var description: string = ""
var assetWebsiteUrl: string = ""
var builtOn: string = ""
var smartContractAddress: string = ""
if(tokenDetails.hasKey(tokenDto.symbol)):
description = tokenDetails[tokenDto.symbol]["Description"]
assetWebsiteUrl = tokenDetails[tokenDto.symbol]["AssetWebsiteUrl"]
builtOn = tokenDetails[tokenDto.symbol]["BuiltOn"]
smartContractAddress = tokenDetails[tokenDto.symbol]["SmartContractAddress"]
if(marketValues.hasKey(tokenDto.symbol)):
marketCap = marketValues[tokenDto.symbol]["MKTCAP"]
highDay = marketValues[tokenDto.symbol]["HIGHDAY"]
lowDay = marketValues[tokenDto.symbol]["LOWDAY"]
changePctHour = marketValues[tokenDto.symbol]["CHANGEPCTHOUR"]
changePctDay = marketValues[tokenDto.symbol]["CHANGEPCTDAY"]
changePct24hour = marketValues[tokenDto.symbol]["CHANGEPCT24HOUR"]
change24hour = marketValues[tokenDto.symbol]["CHANGE24HOUR"]
let tokenDescription = description.multiReplace([("|", ""),("Facebook",""),("Telegram",""),("Discord",""),("Youtube",""),("YouTube",""),("Instagram",""),("Reddit",""),("Github",""),("GitHub",""),("Whitepaper",""),("Medium",""),("Weibo",""),("LinkedIn",""),("Litepaper",""),("KakaoTalk",""),("BitcoinTalk",""),("Slack",""),("Docs",""),("Kakao",""),("Gitter","")])
builtTokens.add(WalletTokenDto(
name: tokenDto.name,
symbol: tokenDto.symbol,
decimals: tokenDto.decimals,
hasIcon: tokenDto.hasIcon,
color: tokenDto.color,
isCustom: tokenDto.isCustom,
totalBalance: totalTokenBalance,
balancesPerChain: balancesPerChain,
enabledNetworkBalance: enabledNetworkBalance,
visible: visible,
description: tokenDescription,
assetWebsiteUrl: assetWebsiteUrl,
builtOn: builtOn,
smartContractAddress: smartContractAddress,
marketCap: marketCap,
highDay: highDay,
lowDay: lowDay,
changePctHour: changePctHour,
changePctDay: changePctDay,
changePct24hour: changePct24hour,
change24hour: change24hour,
currencyPrice: prices[tokenDto.symbol],
)
)
var tokensJArray = newJArray()
for wtDto in builtTokens:
tokensJarray.add(walletTokenDtoToJson(wtDto))
builtTokensPerAccount[address] = tokensJArray
arg.finish(builtTokensPerAccount)
let response = backend.getWalletToken()
arg.finish(response.result)
#################################################
# Async add migrated keypair

View File

@ -8,29 +8,30 @@ const WalletTypeSeed* = "seed"
const WalletTypeWatch* = "watch"
const WalletTypeKey* = "key"
var alwaysVisible = {
1: @["ETH", "SNT", "DAI"],
10: @["ETH", "SNT", "DAI"],
42161: @["ETH", "SNT", "DAI"],
5: @["ETH", "STT", "DAI"],
420: @["ETH", "STT", "DAI"],
421613: @["ETH", "STT", "DAI"],
}.toTable
type BalanceDto* = object
balance*: float64
currencyBalance*: float64
address*: string
chainId*: int
enabled*: bool
type
WalletTokenDto* = object
name*: string
symbol*: string
decimals*: int
hasIcon*: bool
color*: string
isCustom*: bool
totalBalance*: BalanceDto
enabledNetworkBalance*: BalanceDto
balancesPerChain*: Table[int, BalanceDto]
visible*: bool
description*: string
assetWebsiteUrl*: string
builtOn*: string
smartContractAddress*: string
marketCap*: string
highDay*: string
lowDay*: string
@ -99,30 +100,67 @@ proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
discard jsonObj.getProp("emoji", result.emoji)
discard jsonObj.getProp("derived-from", result.derivedfrom)
proc getCurrencyBalance*(self: WalletAccountDto): float64 =
return self.tokens.map(t => t.enabledNetworkBalance.currencyBalance).foldl(a + b, 0.0)
proc getCurrencyBalance*(self: BalanceDto, currencyPrice: float64): float64 =
return self.balance * currencyPrice
proc getAddress*(self: WalletTokenDto): string =
for balance in self.balancesPerChain.values:
return balance.address
return ""
proc getBalances*(self: WalletTokenDto, chainIds: seq[int]): seq[BalanceDto] =
for chainId in chainIds:
if self.balancesPerChain.hasKey(chainId):
result.add(self.balancesPerChain[chainId])
proc getCurrencyBalance*(self: WalletTokenDto, chainIds: seq[int]): float64 =
var sum = 0.0
for chainId in chainIds:
if self.balancesPerChain.hasKey(chainId):
sum += self.balancesPerChain[chainId].getCurrencyBalance(self.currencyPrice)
return sum
proc getVisible*(self: WalletTokenDto, chainIds: seq[int]): bool =
for chainId in chainIds:
if alwaysVisible.hasKey(chainId) and self.symbol in alwaysVisible[chainId]:
return true
if self.balancesPerChain.hasKey(chainId) and self.balancesPerChain[chainId].balance > 0:
return true
return false
proc getCurrencyBalance*(self: WalletAccountDto, chainIds: seq[int]): float64 =
return self.tokens.map(t => t.getCurrencyBalance(chainIds)).foldl(a + b, 0.0)
proc getBalance*(self: WalletTokenDto, chainIds: seq[int]): float64 =
var sum = 0.0
for chainId in chainIds:
if self.balancesPerChain.hasKey(chainId):
sum += self.balancesPerChain[chainId].balance
return sum
proc getBalance*(self: WalletAccountDto, chainIds: seq[int]): float64 =
return self.tokens.map(t => t.getBalance(chainIds)).foldl(a + b, 0.0)
proc toBalanceDto*(jsonObj: JsonNode): BalanceDto =
result = BalanceDto()
discard jsonObj.getProp("balance", result.balance)
discard jsonObj.getProp("currencyBalance", result.currencyBalance)
result.balance = jsonObj{"balance"}.getStr.parseFloat()
discard jsonObj.getProp("address", result.address)
discard jsonObj.getProp("chainId", result.chainId)
discard jsonObj.getProp("enabled", result.enabled)
proc toWalletTokenDto*(jsonObj: JsonNode): WalletTokenDto =
result = WalletTokenDto()
discard jsonObj.getProp("name", result.name)
discard jsonObj.getProp("symbol", result.symbol)
discard jsonObj.getProp("decimals", result.decimals)
discard jsonObj.getProp("hasIcon", result.hasIcon)
discard jsonObj.getProp("color", result.color)
discard jsonObj.getProp("isCustom", result.isCustom)
discard jsonObj.getProp("visible", result.visible)
discard jsonObj.getProp("description", result.description)
discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl)
discard jsonObj.getProp("builtOn", result.builtOn)
discard jsonObj.getProp("smartContractAddress", result.smartContractAddress)
discard jsonObj.getProp("marketCap", result.marketCap)
discard jsonObj.getProp("highDay", result.highDay)
discard jsonObj.getProp("lowDay", result.lowDay)
@ -132,45 +170,7 @@ proc toWalletTokenDto*(jsonObj: JsonNode): WalletTokenDto =
discard jsonObj.getProp("change24hour", result.change24hour)
discard jsonObj.getProp("currencyPrice", result.currencyPrice)
var totalBalanceObj: JsonNode
if(jsonObj.getProp("totalBalance", totalBalanceObj)):
result.totalBalance = toBalanceDto(totalBalanceObj)
var enabledNetworkBalanceObj: JsonNode
if(jsonObj.getProp("enabledNetworkBalance", enabledNetworkBalanceObj)):
result.enabledNetworkBalance = toBalanceDto(enabledNetworkBalanceObj)
var balancesPerChainObj: JsonNode
if(jsonObj.getProp("balancesPerChain", balancesPerChainObj)):
for chainId, balanceObj in balancesPerChainObj:
result.balancesPerChain[parseInt(chainId)] = toBalanceDto(balanceObj)
proc walletTokenDtoToJson*(dto: WalletTokenDto): JsonNode =
var balancesPerChainJsonObj = newJObject()
for k, v in dto.balancesPerChain.pairs:
balancesPerChainJsonObj[$k] = %* v
result = %* {
"name": dto.name,
"symbol": dto.symbol,
"decimals": dto.decimals,
"hasIcon": dto.hasIcon,
"color": dto.color,
"isCustom": dto.isCustom,
"totalBalance": %* dto.totalBalance,
"enabledNetworkBalance": %* dto.enabledNetworkBalance,
"balancesPerChain": balancesPerChainJsonObj,
"visible": dto.visible,
"description": dto.description,
"assetWebsiteUrl": dto.assetWebsiteUrl,
"builtOn": dto.builtOn,
"smartContractAddress": dto.smartContractAddress,
"marketCap": dto.marketCap,
"highDay": dto.highDay,
"lowDay": dto.lowDay,
"changePctHour": dto.changePctHour,
"changePctDay": dto.changePctDay,
"changePct24hour": dto.changePct24hour,
"change24hour": dto.change24hour,
"currencyPrice": dto.currencyPrice,
}
result.balancesPerChain[parseInt(chainId)] = toBalanceDto(balanceObj)

View File

@ -248,9 +248,6 @@ QtObject:
error "error: ", errDescription
return
proc getCurrencyBalance*(self: Service): float64 =
return self.getWalletAccounts().map(a => a.getCurrencyBalance()).foldl(a + b, 0.0)
proc addNewAccountToLocalStore(self: Service) =
let accounts = self.fetchAccounts()
var newAccount = accounts[0]
@ -360,21 +357,13 @@ QtObject:
self.buildAllTokens()
self.events.emit(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED, CurrencyUpdated())
proc toggleTokenVisible*(self: Service, chainId: int, address: string) =
self.tokenService.toggleVisible(chainId, address)
self.buildAllTokens()
self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED, TokenVisibilityToggled())
proc toggleNetworkEnabled*(self: Service, chainId: int) =
self.networkService.toggleNetwork(chainId)
self.tokenService.init()
self.buildAllTokens()
self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled())
method toggleTestNetworksEnabled*(self: Service) =
discard self.settingsService.toggleTestNetworksEnabled()
self.tokenService.init()
self.buildAllTokens()
self.checkRecentHistory()
self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled())
@ -488,24 +477,23 @@ QtObject:
self.threadpool.start(arg)
proc onAllTokensBuilt*(self: Service, response: string) {.slot.} =
let responseObj = response.parseJson
if (responseObj.kind != JObject):
info "prepared tokens are not a json object"
return
try:
let responseObj = response.parseJson
var data = TokensPerAccountArgs()
let walletAddresses = toSeq(self.walletAccounts.keys)
for wAddress in walletAddresses:
var tokensArr: JsonNode
var tokens: seq[WalletTokenDto]
if(responseObj.getProp(wAddress, tokensArr)):
tokens = map(tokensArr.getElems(), proc(x: JsonNode): WalletTokenDto = x.toWalletTokenDto())
tokens.sort(priorityTokenCmp)
self.walletAccounts[wAddress].tokens = tokens
data.accountsTokens[wAddress] = tokens
var data = TokensPerAccountArgs()
let walletAddresses = toSeq(self.walletAccounts.keys)
for wAddress in walletAddresses:
var tokensArr: JsonNode
var tokens: seq[WalletTokenDto]
if(responseObj.getProp(wAddress, tokensArr)):
tokens = map(tokensArr.getElems(), proc(x: JsonNode): WalletTokenDto = x.toWalletTokenDto())
tokens.sort(priorityTokenCmp)
self.walletAccounts[wAddress].tokens = tokens
data.accountsTokens[wAddress] = tokens
self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT, data)
self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT, data)
except Exception as e:
error "error: ", procName="onAllTokensBuilt", errName = e.name, errDesription = e.msg
# run timer again...
self.startBuildingTokensTimer()
@ -520,15 +508,10 @@ QtObject:
if not calledFromTimerOrInit:
self.ignoreTimeInitiatedTokensBuild = true
let walletAddresses = toSeq(self.walletAccounts.keys)
let arg = BuildTokensTaskArg(
tptr: cast[ByteAddress](prepareTokensTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAllTokensBuilt",
walletAddresses: walletAddresses,
currency: self.settingsService.getCurrency(),
networks: self.networkService.getNetworks()
)
self.threadpool.start(arg)
@ -537,34 +520,18 @@ QtObject:
proc getNetworkCurrencyBalance*(self: Service, network: NetworkDto): float64 =
for walletAccount in toSeq(self.walletAccounts.values):
for token in walletAccount.tokens:
if token.balancesPerChain.hasKey(network.chainId):
let balance = token.balancesPerChain[network.chainId]
result += balance.currencyBalance
result += walletAccount.getCurrencyBalance(@[network.chainId])
proc findTokenSymbolByAddress*(self: Service, address: string): string =
return self.tokenService.findTokenSymbolByAddressInAllNetworks(address)
return self.tokenService.findTokenSymbolByAddress(address)
proc fetchBalanceForAddress*(self: Service, address: string): float64 =
let currency = self.settingsService.getCurrency()
let networks = self.networkService.getNetworks()
var networkSymbols: seq[string]
var allTokens: seq[TokenDto]
for n in networks:
networkSymbols.add(n.nativeCurrencySymbol)
allTokens.add(getTokensForChainId(n))
allTokens.add(getCustomTokens())
allTokens = deduplicate(allTokens)
proc getCurrencyBalanceForAddress*(self: Service, address: string): float64 =
let chainIds = self.networkService.getNetworks().map(n => n.chainId)
return self.walletAccounts[address].getCurrencyBalance(chainIds)
var prices = fetchPrices(networkSymbols, allTokens, currency)
let tokenBalances = getTokensBalances(@[address], allTokens)
var totalBalance = 0.0
for token in allTokens:
let balanceForToken = tokenBalances{address}{token.addressAsString()}.getStr
let chainBalanceForToken = parsefloat(hex2Balance(balanceForToken, token.decimals))
totalBalance = totalBalance + chainBalanceForToken * prices[token.symbol]
return totalBalance
proc getTotalCurrencyBalance*(self: Service): float64 =
let chainIds = self.networkService.getNetworks().filter(a => a.enabled).map(a => a.chainId)
return self.getWalletAccounts().map(a => a.getCurrencyBalance(chainIds)).foldl(a + b, 0.0)
proc responseHasNoErrors(self: Service, procName: string, response: RpcResponse[JsonNode]): bool =
var errMsg = ""

View File

@ -48,16 +48,6 @@ type
rpc(clientVersion, "web3"):
discard
rpc(getCustomTokens, "wallet"):
discard
rpc(deleteCustomTokenByChainID, "wallet"):
chainId: int
address: string
rpc(addCustomToken, "wallet"):
token: Token
rpc(getOpenseaCollectionsByOwner, "wallet"):
chainId: int
address: string
@ -95,16 +85,11 @@ rpc(getTokensBalancesForChainIDs, "wallet"):
accounts: seq[string]
tokens: seq[string]
rpc(discoverToken, "wallet"):
chainId: int
address: string
rpc(getPendingTransactionsByChainIDs, "wallet"):
chainIds: seq[int]
rpc(toggleVisibleToken, "wallet"):
chainId: int
address: string
rpc(getWalletToken, "wallet"):
discard
rpc(getTransactionEstimatedTime, "wallet"):
chainId: int

View File

@ -1,172 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Dialogs 1.3
import utils 1.0
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import shared.controls 1.0
import "../stores"
StatusModal {
id: popup
property bool editable: true
property int marginBetweenInputs: 35
property string validationError: ""
property WalletStore walletStore
header.title: editable ?
qsTr("Add custom token")
: nameInput.text
x: Math.round(((parent ? parent.width : 0) - width) / 2)
y: Math.round(((parent ? parent.height : 0) - height) / 2)
height: editable ? 450 : 380
onOpened: {
addressInput.forceActiveFocus(Qt.MouseFocusReason)
}
function openEditable(){
addressInput.text = "";
nameInput.text = "";
symbolInput.text = "";
decimalsInput.text = "";
editable = true;
open();
}
function openWithData(chainId, address, name, symbol, decimals){
addressInput.text = address;
nameInput.text = name;
symbolInput.text = symbol;
decimalsInput.text = decimals;
editable = false;
open();
}
function validate() {
if (addressInput.text !== "" && !Utils.isAddress(addressInput.text)) {
validationError = qsTr("This needs to be a valid address");
}
return validationError === ""
}
property var getTokenDetails: Backpressure.debounce(popup, 500, function (tokenAddress){
popup.walletStore.walletTokensModule.getTokenDetails(tokenAddress)
});
function onKeyReleased(){
validationError = "";
if (!validate() || addressInput.text === "") {
return;
}
Qt.callLater(getTokenDetails, addressInput.text)
}
Connections {
target: popup.walletStore.walletTokensModule
onTokenDetailsWereResolved: {
const jsonObj = JSON.parse(tokenDetails)
if (jsonObj.error) {
validationError = jsonObj.error
return
}
if (jsonObj.name === "" && jsonObj.symbol === "" && jsonObj.decimals === "") {
validationError = qsTr("Invalid ERC20 address")
return;
}
if (addressInput.text.toLowerCase() === jsonObj.address.toLowerCase()) {
symbolInput.text = jsonObj.symbol;
decimalsInput.text = jsonObj.decimals;
nameInput.text = jsonObj.name;
}
}
}
contentItem: Item {
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Style.current.padding
anchors.rightMargin: Style.current.padding
Input {
id: addressInput
anchors.left: parent.left
anchors.right: parent.right
readOnly: !editable
textField.maximumLength: 42
placeholderText: qsTr("Enter contract address...")
label: qsTr("Contract address")
validationError: popup.validationError
Keys.onReleased: onKeyReleased()
}
Input {
id: nameInput
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressInput.bottom
anchors.topMargin: marginBetweenInputs
readOnly: !editable
placeholderText: qsTr("The name of your token...")
label: qsTr("Name")
}
Input {
id: symbolInput
readOnly: !editable
placeholderText: qsTr("ABC")
label: qsTr("Symbol")
anchors.top: nameInput.bottom
anchors.topMargin: marginBetweenInputs
anchors.left: parent.left
anchors.right: undefined
width: parent.width / 2 - 20
}
Input {
id: decimalsInput
readOnly: !editable
placeholderText: "18"
label: qsTr("Decimals")
text: "18"
anchors.top: nameInput.bottom
anchors.topMargin: marginBetweenInputs
anchors.right: parent.right
anchors.left: undefined
width: parent.width / 2 - 20
}
}
MessageDialog {
id: changeError
title: qsTr("Changing settings failed")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
rightButtons: [
StatusButton {
text: qsTr("Add")
enabled: validationError === "" && addressInput.text !== "" && nameInput.text !== "" && symbolInput.text !== "" && decimalsInput.text !== ""
visible: editable
onClicked: {
const error = popup.walletStore.addCustomToken(0, addressInput.text, nameInput.text, symbolInput.text, decimalsInput.text);
if (error) {
Global.playErrorSound();
changeError.text = error;
changeError.open();
return;
}
popup.close();
}
}
]
}

View File

@ -1,54 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import utils 1.0
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import "../panels"
import "../stores"
StatusModal {
id: popup
x: Math.round(((parent ? parent.width : 0) - width) / 2)
y: Math.round(((parent ? parent.height : 0) - height) / 2)
height: 480
property WalletStore walletStore
header.title: qsTr("Manage Assets")
rightButtons: [
StatusButton {
text: qsTr("Add custom token")
onClicked: {
addShowTokenModal.openEditable();
}
}
]
contentItem: TokenSettingsModalContent {
id: settingsModalContent
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Style.current.padding
anchors.rightMargin: Style.current.padding
defaultTokenList: walletStore.defaultTokenList
customTokenList: walletStore.customTokenList
onToggleVisibleClicked: {
walletStore.toggleVisible(chainId, address)
}
onRemoveCustomTokenTriggered: {
walletStore.removeCustomToken(chainId, address)
}
onShowTokenDetailsTriggered: {
addShowTokenModal.openWithData(chainId, address, name, symbol, decimals);
}
AddShowTokenModal{
id: addShowTokenModal
walletStore: root.walletStore
}
}
}

View File

@ -21,25 +21,9 @@ QtObject {
property var importedAccounts: walletSectionAccounts.imported
property var generatedAccounts: walletSectionAccounts.generated
property var watchOnlyAccounts: walletSectionAccounts.watchOnly
property var walletTokensModule: walletSectionAllTokens
property var defaultTokenList: walletSectionAllTokens.default
property var customTokenList: walletSectionAllTokens.custom
property var currencyStore: SharedStore.RootStore.currencyStore
function addCustomToken(chainId, address, name, symbol, decimals) {
return walletSectionAllTokens.addCustomToken(chainId, address, name, symbol, decimals)
}
function toggleVisible(chainId, address) {
walletSectionAllTokens.toggleVisible(chainId, address)
}
function removeCustomToken(chainId, address) {
walletSectionAllTokens.removeCustomToken(chainId, address)
}
property var currentAccount: walletSectionCurrent
function switchAccountByAddress(address) {

View File

@ -20,33 +20,6 @@ Column {
signal goToAccountView(address: string)
signal goToDappPermissionsView()
// Temporary commented, we need to bring it back after MVP
// https://github.com/status-im/status-desktop/issues/5856
// StatusListItem {
// title: qsTr("Manage Assets & List")
// height: 64
// width: parent.width
// onClicked: Global.openPopup(tokenSettingsModalComponent)
// components: [
// StatusIcon {
// icon: "chevron-down"
// rotation: 270
// color: Theme.palette.baseColor1
// }
// ]
// }
Component {
id: tokenSettingsModalComponent
TokenSettingsModal {
walletStore: root.walletStore
onClosed: {
destroy();
}
}
}
Separator {
height: 17
}

View File

@ -31,9 +31,6 @@ QtObject {
property string signingPhrase: walletSection.signingPhrase
property string mnemonicBackedUp: walletSection.isMnemonicBackedUp
property var walletTokensModule: walletSectionAllTokens
property var tokens: walletSectionAllTokens.all
property var collectionList: walletSectionCollectiblesCollections.model
property var collectibleLists: walletSectionCollectiblesCollectibles.model
property var currentCollectible: walletSectionCollectibleCurrent

View File

@ -10,11 +10,6 @@ Item {
id: assetDelegate
objectName: symbol
QtObject {
id: _internal
readonly property var alwaysVisible : ["ETH", "SNT", "DAI", "STT"]
}
property string locale: ""
property string currency: ""
property string currencySymbol: ""
@ -22,7 +17,7 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
visible: _internal.alwaysVisible.includes(symbol) || (networkVisible && enabledNetworkBalance > 0)
visible: networkVisible
height: visible ? 40 + 2 * Style.current.padding : 0
Image {

View File

@ -77,7 +77,6 @@ Control {
id: chainRepeater
model: balances ? balances : null
delegate: InformationTag {
visible: model.enabled
tagPrimaryLabel.text: model.balance
tagPrimaryLabel.color: root.getNetworkColor(model.chainId)
image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(model.chainId)))

View File

@ -76,7 +76,9 @@ Item {
ExpressionFilter {
expression: {
var tokenSymbolByAddress = searchTokenSymbolByAddressFn(d.searchString)
return symbol.startsWith(d.searchString.toUpperCase()) || name.toUpperCase().startsWith(d.searchString.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
return networkVisible && (
symbol.startsWith(d.searchString.toUpperCase()) || name.toUpperCase().startsWith(d.searchString.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
)
}
}
]

View File

@ -39,10 +39,6 @@ QtObject {
property bool isNonArchivalNode: history.isNonArchivalNode
property var currentAccount: walletSectionCurrent
property var walletTokensModule: walletSectionAllTokens
property var tokens: walletSectionAllTokens.all
property var accounts: walletSectionAccounts.model
property var marketValueStore: TokenMarketValuesStore{}
function getNetworkColor(chainId) {

View File

@ -374,10 +374,10 @@ Item {
image.source: token && token.builtOn !== "" ? Style.svg("tiny/" + RootStore.getNetworkIconUrl(token.builtOn)) : ""
tagPrimaryLabel.text: token && token.builtOn !== "" ? RootStore.getNetworkName(token.builtOn) : "---"
tagSecondaryLabel.text: token && token.smartContractAddress !== "" ? token.smartContractAddress : "---"
tagSecondaryLabel.text: token && token.address !== "" ? token.address : "---"
controlBackground.color: Theme.palette.baseColor2
controlBackground.border.color: "transparent"
visible: typeof token != "undefined" && token && token.builtOn !== "" && token.smartContractAddress !== ""
visible: typeof token != "undefined" && token && token.builtOn !== "" && token.address !== ""
}
}
}

View File

@ -23,7 +23,6 @@ Item {
QtObject {
id: d
readonly property var alwaysVisible : ["ETH", "SNT", "DAI", "STT"]
property int selectedAssetIndex: -1
}
@ -37,7 +36,7 @@ Item {
sourceModel: account.assets
filters: [
ExpressionFilter {
expression: d.alwaysVisible.includes(symbol) || (networkVisible && enabledNetworkBalance > 0)
expression: networkVisible
}
]
}

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 194f26f3b4503494702be4e8148a166f61730c4d
Subproject commit eff02a79a986611fd4ef0302a59ac8c86e250641