feat(@desktop/wallet): implement unified currency formatting

Fixes #8640
This commit is contained in:
Dario Gabriel Lipicar 2022-12-29 13:44:51 -03:00 committed by dlipicar
parent 00817aedf9
commit 7c4022e4ac
79 changed files with 1121 additions and 455 deletions

View File

@ -10,6 +10,7 @@ import ../../app_service/service/chat/service as chat_service
import ../../app_service/service/community/service as community_service import ../../app_service/service/community/service as community_service
import ../../app_service/service/message/service as message_service import ../../app_service/service/message/service as message_service
import ../../app_service/service/token/service as token_service import ../../app_service/service/token/service as token_service
import ../../app_service/service/currency/service as currency_service
import ../../app_service/service/transaction/service as transaction_service import ../../app_service/service/transaction/service as transaction_service
import ../../app_service/service/collectible/service as collectible_service import ../../app_service/service/collectible/service as collectible_service
import ../../app_service/service/wallet_account/service as wallet_account_service import ../../app_service/service/wallet_account/service as wallet_account_service
@ -67,6 +68,7 @@ type
communityService: community_service.Service communityService: community_service.Service
messageService: message_service.Service messageService: message_service.Service
tokenService: token_service.Service tokenService: token_service.Service
currencyService: currency_service.Service
transactionService: transaction_service.Service transactionService: transaction_service.Service
collectibleService: collectible_service.Service collectibleService: collectible_service.Service
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
@ -160,6 +162,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.tokenService = token_service.newService( result.tokenService = token_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.networkService statusFoundation.events, statusFoundation.threadpool, result.networkService
) )
result.currencyService = currency_service.newService(result.tokenService, result.settingsService)
result.collectibleService = collectible_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService) result.collectibleService = collectible_service.newService(statusFoundation.events, statusFoundation.threadpool, result.networkService)
result.walletAccountService = wallet_account_service.newService( result.walletAccountService = wallet_account_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.settingsService, result.accountsService, statusFoundation.events, statusFoundation.threadpool, result.settingsService, result.accountsService,
@ -221,6 +224,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.communityService, result.communityService,
result.messageService, result.messageService,
result.tokenService, result.tokenService,
result.currencyService,
result.transactionService, result.transactionService,
result.collectibleService, result.collectibleService,
result.walletAccountService, result.walletAccountService,
@ -273,6 +277,7 @@ proc delete*(self: AppController) =
self.accountsService.delete self.accountsService.delete
self.chatService.delete self.chatService.delete
self.communityService.delete self.communityService.delete
self.currencyService.delete
self.tokenService.delete self.tokenService.delete
self.transactionService.delete self.transactionService.delete
self.collectibleService.delete self.collectibleService.delete
@ -352,6 +357,7 @@ proc load(self: AppController) =
self.networkService.init() self.networkService.init()
self.tokenService.init() self.tokenService.init()
self.currencyService.init()
self.walletAccountService.init() self.walletAccountService.init()
# Apply runtime log level settings # Apply runtime log level settings

View File

@ -1,23 +1,31 @@
import sugar, sequtils import sugar, sequtils, Tables
import io_interface import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/token/service as token_service
import ../../../../../app_service/service/currency/service as currency_service
type type
Controller* = ref object of RootObj Controller* = ref object of RootObj
delegate: io_interface.AccessInterface delegate: io_interface.AccessInterface
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
networkService: network_service.Service networkService: network_service.Service
tokenService: token_service.Service
currencyService: currency_service.Service
proc newController*( proc newController*(
delegate: io_interface.AccessInterface, delegate: io_interface.AccessInterface,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service,
): Controller = ): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.networkService = networkService result.networkService = networkService
result.tokenService = tokenService
result.currencyService = currencyService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -38,4 +46,13 @@ proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId) return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] = proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId) return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
proc getCurrentCurrency*(self: Controller): string =
return self.walletAccountService.getCurrency()
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
return self.currencyService.getCurrencyFormat(symbol)
proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] =
return self.walletAccountService.getAllMigratedKeyPairs()

View File

@ -1,11 +1,16 @@
import NimQml, Tables, sequtils import NimQml, Tables, sequtils, sugar
import ../../../../global/global_singleton import ../../../../global/global_singleton
import ../../../../core/eventemitter import ../../../../core/eventemitter
import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/token/service as token_service
import ../../../../../app_service/service/currency/service as currency_service
import ../../../shared_models/token_model as token_model import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item import ../../../shared_models/token_item as token_item
import ../../../shared_models/token_utils
import ../../wallet_section/accounts/utils
import ./io_interface, ./view, ./controller import ./io_interface, ./view, ./controller
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
@ -28,57 +33,64 @@ proc newModule*(
events: EventEmitter, events: EventEmitter,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service,
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.events = events result.events = events
result.currentAccountIndex = 0 result.currentAccountIndex = 0
result.view = newView(result) result.view = newView(result)
result.controller = newController(result, walletAccountService, networkService) result.controller = newController(result, walletAccountService, networkService, tokenService, currencyService)
result.moduleLoaded = false result.moduleLoaded = false
method delete*(self: Module) = method delete*(self: Module) =
self.view.delete self.view.delete
proc setAssets(self: Module, tokens: seq[WalletTokenDto]) = proc setAssets(self: Module, tokens: seq[WalletTokenDto]) =
var items: seq[Item]
let chainIds = self.controller.getChainIds() let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds() let enabledChainIds = self.controller.getEnabledChainIds()
for t in tokens: let currency = self.controller.getCurrentCurrency()
let item = token_item.initItem(
t.name, let currencyFormat = self.controller.getCurrencyFormat(currency)
t.symbol,
t.getBalance(chainIds), let items = tokens.map(t => walletTokenToItem(t, chainIds, enabledChainIds, currency, currencyFormat, self.controller.getCurrencyFormat(t.symbol)))
t.getCurrencyBalance(chainIds),
t.getBalance(enabledChainIds),
t.getCurrencyBalance(enabledChainIds),
t.getVisibleForNetwork(enabledChainIds),
t.getVisibleForNetworkWithPositiveBalance(enabledChainIds),
t.getBalances(enabledChainIds),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.getAddress(),
t.marketCap,
t.highDay,
t.lowDay,
t.changePctHour,
t.changePctDay,
t.changePct24hour,
t.change24hour,
t.currencyPrice,
t.decimals,
)
items.add(item)
self.view.getAssetsModel().setItems(items) self.view.getAssetsModel().setItems(items)
method switchAccount*(self: Module, accountIndex: int) = method switchAccount*(self: Module, accountIndex: int) =
self.currentAccountIndex = accountIndex self.currentAccountIndex = accountIndex
let keyPairMigrated = proc(migratedKeyPairs: seq[KeyPairDto], keyUid: string): bool =
for kp in migratedKeyPairs:
if kp.keyUid == keyUid:
return true
return false
let walletAccount = self.controller.getWalletAccount(accountIndex) let walletAccount = self.controller.getWalletAccount(accountIndex)
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
let currency = self.controller.getCurrentCurrency()
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds() let enabledChainIds = self.controller.getEnabledChainIds()
self.view.setData(walletAccount, enabledChainIds)
let tokenFormats = collect(initTable()):
for t in walletAccount.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
let currencyFormat = self.controller.getCurrencyFormat(currency)
let accountItem = walletAccountToItem(
walletAccount,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, walletAccount.keyUid),
currencyFormat,
tokenFormats
)
self.view.setData(accountItem)
self.setAssets(walletAccount.tokens) self.setAssets(walletAccount.tokens)
method load*(self: Module) = method load*(self: Module) =

View File

@ -1,10 +1,11 @@
import NimQml, sequtils, sugar import NimQml, sequtils, sugar
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ./io_interface import ./io_interface
import ../../../shared_models/token_model as token_model import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item import ../../../shared_models/token_item as token_item
import ../../../shared_models/currency_amount
import ../../wallet_section/accounts/item as account_item
QtObject: QtObject:
type type
@ -17,7 +18,7 @@ QtObject:
publicKey: string publicKey: string
walletType: string walletType: string
isChat: bool isChat: bool
currencyBalance: float64 currencyBalance: CurrencyAmount
assets: token_model.Model assets: token_model.Model
emoji: string emoji: string
@ -140,27 +141,27 @@ QtObject:
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} = proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas) return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas)
proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): string {.slot.} = # proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): QVariant {.slot.} =
return self.assets.getTokenBalanceOnChain(chainId, tokenSymbol) # return newQVariant(self.assets.getTokenBalanceOnChain(chainId, tokenSymbol))
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto, chainIds: seq[int]) = proc setData*(self: View, item: account_item.Item) =
self.name = dto.name self.name = item.getName()
self.nameChanged() self.nameChanged()
self.address = dto.address self.address = item.getAddress()
self.addressChanged() self.addressChanged()
self.path = dto.path self.path = item.getPath()
self.pathChanged() self.pathChanged()
self.color = dto.color self.color = item.getColor()
self.colorChanged() self.colorChanged()
self.publicKey = dto.publicKey self.publicKey = item.getPublicKey()
self.publicKeyChanged() self.publicKeyChanged()
self.walletType = dto.walletType self.walletType = item.getWalletType()
self.walletTypeChanged() self.walletTypeChanged()
self.isChat = dto.isChat self.isChat = item.getIsChat()
self.isChatChanged() self.isChatChanged()
self.currencyBalance = dto.getCurrencyBalance(chainIds) self.currencyBalance = item.getCurrencyBalance()
self.currencyBalanceChanged() self.currencyBalanceChanged()
self.emoji = dto.emoji self.emoji = item.getEmoji()
self.emojiChanged() self.emojiChanged()
proc isAddressCurrentAccount*(self: View, address: string): bool = proc isAddressCurrentAccount*(self: View, address: string): bool =

View File

@ -14,6 +14,8 @@ import ../../../../app_service/service/network/service as network_service
import ../../../../app_service/service/dapp_permissions/service as dapp_permissions_service import ../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../../../app_service/service/provider/service as provider_service import ../../../../app_service/service/provider/service as provider_service
import ../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/token/service as token_service
import ../../../../app_service/service/currency/service as currency_service
export io_interface export io_interface
@ -36,7 +38,10 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
networkService: network_service.Service, networkService: network_service.Service,
dappPermissionsService: dapp_permissions_service.Service, dappPermissionsService: dapp_permissions_service.Service,
providerService: provider_service.Service, providerService: provider_service.Service,
walletAccountService: wallet_account_service.Service): Module = walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service
): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.events = events result.events = events
@ -46,7 +51,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
result.providerModule = provider_module.newModule(result, events, settingsService, networkService, providerService) result.providerModule = provider_module.newModule(result, events, settingsService, networkService, providerService)
result.bookmarkModule = bookmark_module.newModule(result, events, bookmarkService) result.bookmarkModule = bookmark_module.newModule(result, events, bookmarkService)
result.dappsModule = dapps_module.newModule(result, dappPermissionsService, walletAccountService) result.dappsModule = dapps_module.newModule(result, dappPermissionsService, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService) result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService)
method delete*(self: Module) = method delete*(self: Module) =
self.view.delete self.view.delete

View File

@ -29,6 +29,7 @@ import ../../../app_service/service/chat/service as chat_service
import ../../../app_service/service/community/service as community_service import ../../../app_service/service/community/service as community_service
import ../../../app_service/service/message/service as message_service import ../../../app_service/service/message/service as message_service
import ../../../app_service/service/token/service as token_service import ../../../app_service/service/token/service as token_service
import ../../../app_service/service/currency/service as currency_service
import ../../../app_service/service/transaction/service as transaction_service import ../../../app_service/service/transaction/service as transaction_service
import ../../../app_service/service/collectible/service as collectible_service import ../../../app_service/service/collectible/service as collectible_service
import ../../../app_service/service/wallet_account/service as wallet_account_service import ../../../app_service/service/wallet_account/service as wallet_account_service
@ -109,6 +110,7 @@ proc newModule*[T](
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
currencyService: currency_service.Service,
transactionService: transaction_service.Service, transactionService: transaction_service.Service,
collectibleService: collectible_service.Service, collectibleService: collectible_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
@ -168,21 +170,22 @@ proc newModule*[T](
# Submodules # Submodules
result.channelGroupModules = initOrderedTable[string, chat_section_module.AccessInterface]() result.channelGroupModules = initOrderedTable[string, chat_section_module.AccessInterface]()
result.walletSectionModule = wallet_section_module.newModule( result.walletSectionModule = wallet_section_module.newModule(
result, events, tokenService, result, events, tokenService, currencyService,
transactionService, collectible_service, walletAccountService, transactionService, collectible_service, walletAccountService,
settingsService, savedAddressService, networkService, accountsService, keycardService settingsService, savedAddressService, networkService, accountsService, keycardService
) )
result.browserSectionModule = browser_section_module.newModule( result.browserSectionModule = browser_section_module.newModule(
result, events, bookmarkService, settingsService, networkService, result, events, bookmarkService, settingsService, networkService,
dappPermissionsService, providerService, walletAccountService dappPermissionsService, providerService, walletAccountService,
tokenService, currencyService
) )
result.profileSectionModule = profile_section_module.newModule( result.profileSectionModule = profile_section_module.newModule(
result, events, accountsService, settingsService, stickersService, result, events, accountsService, settingsService, stickersService,
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService, profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
devicesService, mailserversService, chatService, ensService, walletAccountService, generalService, communityService, devicesService, mailserversService, chatService, ensService, walletAccountService, generalService, communityService,
networkService, keycardService, keychainService networkService, keycardService, keychainService, tokenService
) )
result.stickersModule = stickers_module.newModule(result, events, stickersService, settingsService, walletAccountService, networkService) result.stickersModule = stickers_module.newModule(result, events, stickersService, settingsService, walletAccountService, networkService, tokenService)
result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService, result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService,
messageService, chatService) messageService, chatService)
result.communitiesModule = communities_module.newModule(result, events, communityService, contactsService) result.communitiesModule = communities_module.newModule(result, events, communityService, contactsService)

View File

@ -7,7 +7,7 @@ import ../../../../../app_service/service/settings/service as settings_service
import ../../../../../app_service/service/ens/service as ens_service import ../../../../../app_service/service/ens/service as ens_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/token/dto import ../../../../../app_service/service/token/service as token_service
import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
logScope: logScope:
@ -23,11 +23,13 @@ type
ensService: ens_service.Service ensService: ens_service.Service
networkService: network_service.Service networkService: network_service.Service
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
tokenService: token_service.Service
proc newController*( proc newController*(
delegate: io_interface.AccessInterface, events: EventEmitter, delegate: io_interface.AccessInterface, events: EventEmitter,
settingsService: settings_service.Service, ensService: ens_service.Service, settingsService: settings_service.Service, ensService: ens_service.Service,
walletAccountService: wallet_account_service.Service, networkService: network_service.Service, walletAccountService: wallet_account_service.Service, networkService: network_service.Service,
tokenService: token_service.Service
): Controller = ): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
@ -36,6 +38,7 @@ proc newController*(
result.ensService = ensService result.ensService = ensService
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.networkService = networkService result.networkService = networkService
result.tokenService = tokenService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -135,7 +138,7 @@ proc getCurrentCurrency*(self: Controller): string =
return self.settingsService.getCurrency() return self.settingsService.getCurrency()
proc getPrice*(self: Controller, crypto: string, fiat: string): float64 = proc getPrice*(self: Controller, crypto: string, fiat: string): float64 =
return self.walletAccountService.getPrice(crypto, fiat) return self.tokenService.getTokenPrice(crypto, fiat)
proc getStatusToken*(self: Controller): string = proc getStatusToken*(self: Controller): string =
let token = self.ensService.getStatusToken() let token = self.ensService.getStatusToken()

View File

@ -12,6 +12,7 @@ import ../../../../../app_service/service/ens/service as ens_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/ens/utils as ens_utils import ../../../../../app_service/service/ens/utils as ens_utils
import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/token/service as token_service
export io_interface export io_interface
@ -49,12 +50,13 @@ proc newModule*(
settingsService: settings_service.Service, ensService: ens_service.Service, settingsService: settings_service.Service, ensService: ens_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.view = view.newView(result) result.view = view.newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, settingsService, ensService, walletAccountService, networkService) result.controller = controller.newController(result, events, settingsService, ensService, walletAccountService, networkService, tokenService)
result.moduleLoaded = false result.moduleLoaded = false
method delete*(self: Module) = method delete*(self: Module) =

View File

@ -22,6 +22,7 @@ import ../../../../app_service/service/general/service as general_service
import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/community/service as community_service
import ../../../../app_service/service/keycard/service as keycard_service import ../../../../app_service/service/keycard/service as keycard_service
import ../../../../app_service/service/keychain/service as keychain_service import ../../../../app_service/service/keychain/service as keychain_service
import ../../../../app_service/service/token/service as token_service
import ./profile/module as profile_module import ./profile/module as profile_module
import ./contacts/module as contacts_module import ./contacts/module as contacts_module
@ -79,7 +80,8 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
communityService: community_service.Service, communityService: community_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
keycardService: keycard_service.Service, keycardService: keycard_service.Service,
keychainService: keychain_service.Service keychainService: keychain_service.Service,
tokenService: token_service.Service
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
@ -98,7 +100,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
result.syncModule = sync_module.newModule(result, events, settingsService, nodeConfigurationService, mailserversService) result.syncModule = sync_module.newModule(result, events, settingsService, nodeConfigurationService, mailserversService)
result.notificationsModule = notifications_module.newModule(result, events, settingsService, chatService, contactsService) result.notificationsModule = notifications_module.newModule(result, events, settingsService, chatService, contactsService)
result.ensUsernamesModule = ens_usernames_module.newModule( result.ensUsernamesModule = ens_usernames_module.newModule(
result, events, settingsService, ensService, walletAccountService, networkService result, events, settingsService, ensService, walletAccountService, networkService, tokenService
) )
result.communitiesModule = communities_module.newModule(result, communityService) result.communitiesModule = communities_module.newModule(result, communityService)
result.keycardModule = keycard_module.newModule(result, events, keycardService, settingsService, privacyService, result.keycardModule = keycard_module.newModule(result, events, keycardService, settingsService, privacyService,

View File

@ -10,6 +10,7 @@ import ../../../../app_service/service/settings/service as settings_service
import ../../../../app_service/service/network/service as network_service import ../../../../app_service/service/network/service as network_service
import ../../../../app_service/service/eth/utils as eth_utils import ../../../../app_service/service/eth/utils as eth_utils
import ../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/token/service as token_service
import ../../shared_modules/keycard_popup/io_interface as keycard_shared_module import ../../shared_modules/keycard_popup/io_interface as keycard_shared_module
const UNIQUE_BUY_STICKER_TRANSACTION_MODULE_IDENTIFIER* = "StickersSection-TransactionModule" const UNIQUE_BUY_STICKER_TRANSACTION_MODULE_IDENTIFIER* = "StickersSection-TransactionModule"
@ -22,6 +23,7 @@ type
settingsService: settings_service.Service settingsService: settings_service.Service
networkService: network_service.Service networkService: network_service.Service
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
tokenService: token_service.Service
disconnected: bool disconnected: bool
# Forward declaration # Forward declaration
@ -35,6 +37,7 @@ proc newController*(
settingsService: settings_service.Service, settingsService: settings_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
): Controller = ): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
@ -43,6 +46,7 @@ proc newController*(
result.settingsService = settingsService result.settingsService = settingsService
result.networkService = networkService result.networkService = networkService
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.tokenService = tokenService
result.disconnected = false result.disconnected = false
proc delete*(self: Controller) = proc delete*(self: Controller) =
@ -154,7 +158,7 @@ proc getCurrentCurrency*(self: Controller): string =
return self.settingsService.getCurrency() return self.settingsService.getCurrency()
proc getPrice*(self: Controller, crypto: string, fiat: string): float64 = proc getPrice*(self: Controller, crypto: string, fiat: string): float64 =
return self.walletAccountService.getPrice(crypto, fiat) return self.tokenService.getTokenPrice(crypto, fiat)
proc getChainIdForStickers*(self: Controller): int = proc getChainIdForStickers*(self: Controller): int =
return self.networkService.getNetworkForStickers().chainId return self.networkService.getNetworkForStickers().chainId

View File

@ -8,6 +8,7 @@ import ../../../../app_service/service/settings/service as settings_service
import ../../../../app_service/service/network/service as network_service import ../../../../app_service/service/network/service as network_service
import ../../../../app_service/common/conversion as service_conversion import ../../../../app_service/common/conversion as service_conversion
import ../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/token/service as token_service
export io_interface export io_interface
@ -40,12 +41,13 @@ proc newModule*(
settingsService: settings_Service.Service, settingsService: settings_Service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.view = newView(result) result.view = newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, stickersService, settingsService, walletAccountService, networkService) result.controller = controller.newController(result, events, stickersService, settingsService, walletAccountService, networkService, tokenService)
result.moduleLoaded = false result.moduleLoaded = false
singletonInstance.engine.setRootContextProperty("stickersModule", result.viewVariant) singletonInstance.engine.setRootContextProperty("stickersModule", result.viewVariant)

View File

@ -1,5 +1,7 @@
import strformat import strformat
import ../../../shared_models/currency_amount
type type
Item* = object Item* = object
name: string name: string
@ -10,7 +12,7 @@ type
walletType: string walletType: string
isWallet: bool isWallet: bool
isChat: bool isChat: bool
currencyBalance: float64 currencyBalance: CurrencyAmount
emoji: string emoji: string
derivedfrom: string derivedfrom: string
@ -23,7 +25,7 @@ proc initItem*(
walletType: string, walletType: string,
isWallet: bool, isWallet: bool,
isChat: bool, isChat: bool,
currencyBalance: float64, currencyBalance: CurrencyAmount,
emoji: string, emoji: string,
derivedfrom: string derivedfrom: string
): Item = ): Item =
@ -81,7 +83,7 @@ proc getIsWallet*(self: Item): bool =
proc getIsChat*(self: Item): bool = proc getIsChat*(self: Item): bool =
return self.isChat return self.isChat
proc getCurrencyBalance*(self: Item): float64 = proc getCurrencyBalance*(self: Item): CurrencyAmount =
return self.currencyBalance return self.currencyBalance
proc getDerivedFrom*(self: Item): string = proc getDerivedFrom*(self: Item): string =

View File

@ -1,8 +1,11 @@
import sugar, sequtils import sugar, sequtils, tables
import io_interface import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_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/accounts/service as accounts_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/token/service as token_service
import ../../../../../app_service/service/currency/service as currency_service
import ../../../../../app_service/service/currency/dto as currency_dto
import ../../../../global/global_singleton import ../../../../global/global_singleton
import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module
@ -19,6 +22,8 @@ type
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
accountsService: accounts_service.Service accountsService: accounts_service.Service
networkService: network_service.Service networkService: network_service.Service
tokenService: token_service.Service
currencyService: currency_service.Service
proc newController*( proc newController*(
delegate: io_interface.AccessInterface, delegate: io_interface.AccessInterface,
@ -26,6 +31,8 @@ proc newController*(
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
accountsService: accounts_service.Service, accountsService: accounts_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service,
): Controller = ): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
@ -33,6 +40,8 @@ proc newController*(
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.accountsService = accountsService result.accountsService = accountsService
result.networkService = networkService result.networkService = networkService
result.tokenService = tokenService
result.currencyService = currencyService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -112,3 +121,9 @@ proc getChainIds*(self: Controller): seq[int] =
proc getEnabledChainIds*(self: Controller): seq[int] = proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId) return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
proc getCurrentCurrency*(self: Controller): string =
return self.walletAccountService.getCurrency()
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
return self.currencyService.getCurrencyFormat(symbol)

View File

@ -1,44 +1,50 @@
import strformat import strformat
import ../../../shared_models/token_model as token_model import ../../../shared_models/token_model as token_model
import ../../../shared_models/currency_amount
import ./compact_model as compact_model import ./compact_model as compact_model
type type
Item* = object Item* = object
name: string name: string
address: string address: string
mixedCaseAddress: string
path: string path: string
color: string color: string
publicKey: string publicKey: string
walletType: string walletType: string
isWallet: bool isWallet: bool
isChat: bool isChat: bool
currencyBalance: float64 currencyBalance: CurrencyAmount
assets: token_model.Model assets: token_model.Model
emoji: string emoji: string
derivedfrom: string derivedfrom: string
relatedAccounts: compact_model.Model relatedAccounts: compact_model.Model
keyUid: string keyUid: string
migratedToKeycard: bool migratedToKeycard: bool
ens: string
proc initItem*( proc initItem*(
name: string, name: string,
address: string, address: string,
mixedCaseAddress: string,
path: string, path: string,
color: string, color: string,
publicKey: string, publicKey: string,
walletType: string, walletType: string,
isWallet: bool, isWallet: bool,
isChat: bool, isChat: bool,
currencyBalance: float64, currencyBalance: CurrencyAmount,
assets: token_model.Model, assets: token_model.Model,
emoji: string, emoji: string,
derivedfrom: string, derivedfrom: string,
relatedAccounts: compact_model.Model, relatedAccounts: compact_model.Model,
keyUid: string, keyUid: string,
migratedToKeycard: bool migratedToKeycard: bool,
ens: string
): Item = ): Item =
result.name = name result.name = name
result.address = address result.address = address
result.mixedCaseAddress = mixedCaseAddress
result.path = path result.path = path
result.color = color result.color = color
result.publicKey = publicKey result.publicKey = publicKey
@ -52,11 +58,13 @@ proc initItem*(
result.relatedAccounts = relatedAccounts result.relatedAccounts = relatedAccounts
result.keyUid = keyUid result.keyUid = keyUid
result.migratedToKeycard = migratedToKeycard result.migratedToKeycard = migratedToKeycard
result.ens = ens
proc `$`*(self: Item): string = proc `$`*(self: Item): string =
result = fmt"""WalletAccountItem( result = fmt"""WalletAccountItem(
name: {self.name}, name: {self.name},
address: {self.address}, address: {self.address},
mixedCaseAddress: {self.mixedCaseAddress},
path: {self.path}, path: {self.path},
color: {self.color}, color: {self.color},
publicKey: {self.publicKey}, publicKey: {self.publicKey},
@ -69,7 +77,8 @@ proc `$`*(self: Item): string =
derivedfrom: {self.derivedfrom}, derivedfrom: {self.derivedfrom},
relatedAccounts: {self.relatedAccounts} relatedAccounts: {self.relatedAccounts}
keyUid: {self.keyUid}, keyUid: {self.keyUid},
migratedToKeycard: {self.migratedToKeycard} migratedToKeycard: {self.migratedToKeycard},
ens: {self.ens}
]""" ]"""
proc getName*(self: Item): string = proc getName*(self: Item): string =
@ -78,6 +87,9 @@ proc getName*(self: Item): string =
proc getAddress*(self: Item): string = proc getAddress*(self: Item): string =
return self.address return self.address
proc getMixedCaseAddress*(self: Item): string =
return self.mixedCaseAddress
proc getPath*(self: Item): string = proc getPath*(self: Item): string =
return self.path return self.path
@ -99,7 +111,7 @@ proc getIsWallet*(self: Item): bool =
proc getIsChat*(self: Item): bool = proc getIsChat*(self: Item): bool =
return self.isChat return self.isChat
proc getCurrencyBalance*(self: Item): float64 = proc getCurrencyBalance*(self: Item): CurrencyAmount =
return self.currencyBalance return self.currencyBalance
proc getAssets*(self: Item): token_model.Model = proc getAssets*(self: Item): token_model.Model =
@ -116,3 +128,6 @@ proc getKeyUid*(self: Item): string =
proc getMigratedToKeycard*(self: Item): bool = proc getMigratedToKeycard*(self: Item): bool =
return self.migratedToKeycard return self.migratedToKeycard
proc getEns*(self: Item): string =
return self.ens

View File

@ -1,6 +1,6 @@
import tables, NimQml, sequtils, sugar, chronicles import tables, NimQml, sequtils, sugar, chronicles
import ./io_interface, ./view, ./item, ./controller import ./io_interface, ./view, ./item, ./controller, ./utils
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
import ../../../../global/global_singleton import ../../../../global/global_singleton
import ../../../../core/eventemitter import ../../../../core/eventemitter
@ -9,6 +9,8 @@ import ../../../../../app_service/service/keycard/service as keycard_service
import ../../../../../app_service/service/wallet_account/service as wallet_account_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/accounts/service as accounts_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/token/service as token_service
import ../../../../../app_service/service/currency/service as currency_service
import ../../../shared_models/token_model as token_model import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item import ../../../shared_models/token_item as token_item
import ../../../shared_modules/keycard_popup/module as keycard_shared_module import ../../../shared_modules/keycard_popup/module as keycard_shared_module
@ -43,7 +45,9 @@ proc newModule*(
keycardService: keycard_service.Service, keycardService: keycard_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
accountsService: accounts_service.Service, accountsService: accounts_service.Service,
networkService: network_service.Service networkService: network_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
@ -52,7 +56,7 @@ proc newModule*(
result.accountsService = accountsService result.accountsService = accountsService
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.view = newView(result) result.view = newView(result)
result.controller = controller.newController(result, events, walletAccountService, accountsService, networkService) result.controller = controller.newController(result, events, walletAccountService, accountsService, networkService, tokenService, currencyService)
result.moduleLoaded = false result.moduleLoaded = false
method delete*(self: Module) = method delete*(self: Module) =
@ -70,73 +74,27 @@ method refreshWalletAccounts*(self: Module) =
let walletAccounts = self.controller.getWalletAccounts() let walletAccounts = self.controller.getWalletAccounts()
let migratedKeyPairs = self.controller.getAllMigratedKeyPairs() let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
let currency = self.controller.getCurrentCurrency()
let chainIds = self.controller.getChainIds() let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds() let enabledChainIds = self.controller.getEnabledChainIds()
let currencyFormat = self.controller.getCurrencyFormat(currency)
let items = walletAccounts.map(proc (w: WalletAccountDto): item.Item = let items = walletAccounts.map(w => (block:
let assets = token_model.newModel() let tokenFormats = collect(initTable()):
assets.setItems( for t in w.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
w.tokens.map(t => token_item.initItem(
t.name, walletAccountToItem(
t.symbol, w,
t.getBalance(chainIds), chainIds,
t.getCurrencyBalance(chainIds), enabledChainIds,
t.getBalance(enabledChainIds), currency,
t.getCurrencyBalance(enabledChainIds), keyPairMigrated(migratedKeyPairs, w.keyUid),
t.getVisibleForNetwork(enabledChainIds), currencyFormat,
t.getVisibleForNetworkWithPositiveBalance(enabledChainIds), tokenFormats
t.getBalances(enabledChainIds),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.getAddress(),
t.marketCap,
t.highDay,
t.lowDay,
t.changePctHour,
t.changePctDay,
t.changePct24hour,
t.change24hour,
t.currencyPrice,
t.decimals,
))
) )
))
let relatedAccounts = compact_model.newModel()
relatedAccounts.setItems(
w.relatedAccounts.map(x => compact_item.initItem(
x.name,
x.address,
x.path,
x.color,
x.publicKey,
x.walletType,
x.isWallet,
x.isChat,
x.getCurrencyBalance(enabledChainIds),
x.emoji,
x.derivedfrom,
))
)
result = initItem(
w.name,
w.address,
w.path,
w.color,
w.publicKey,
w.walletType,
w.isWallet,
w.isChat,
w.getCurrencyBalance(enabledChainIds),
assets,
w.emoji,
w.derivedfrom,
relatedAccounts,
w.keyUid,
keyPairMigrated(migratedKeyPairs, w.keyUid)
))
self.view.setItems(items) self.view.setItems(items)

View File

@ -0,0 +1,68 @@
import tables, sequtils, sugar
import ./item
import ../../../../../app_service/service/wallet_account/dto
import ../../../../../app_service/service/token/dto as token_dto
import ../../../../../app_service/service/currency/dto as currency_dto
import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item
import ../../../shared_models/token_utils
import ../../../shared_models/currency_amount
import ../../../shared_models/currency_amount_utils
import ./compact_item as compact_item
import ./compact_model as compact_model
proc walletAccountToCompactItem*(w: WalletAccountDto, enabledChainIds: seq[int], currency: string, currencyFormat: CurrencyFormatDto) : compact_item.Item =
return compact_item.initItem(
w.name,
w.address,
w.path,
w.color,
w.publicKey,
w.walletType,
w.isWallet,
w.isChat,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
w.emoji,
w.derivedfrom)
proc walletAccountToItem*(
w: WalletAccountDto,
chainIds: seq[int],
enabledChainIds: seq[int],
currency: string,
keyPairMigrated: bool,
currencyFormat: CurrencyFormatDto,
tokenFormats: Table[string, CurrencyFormatDto],
) : item.Item =
let assets = token_model.newModel()
assets.setItems(
w.tokens.map(t => walletTokenToItem(t, chainIds, enabledChainIds, currency, currencyFormat, tokenFormats[t.symbol]))
)
let relatedAccounts = compact_model.newModel()
relatedAccounts.setItems(
w.relatedAccounts.map(x => walletAccountToCompactItem(x, enabledChainIds, currency, currencyFormat))
)
result = initItem(
w.name,
w.address,
w.mixedCaseAddress,
w.path,
w.color,
w.publicKey,
w.walletType,
w.isWallet,
w.isChat,
currencyAmountToItem(w.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
assets,
w.emoji,
w.derivedfrom,
relatedAccounts,
w.keyUid,
keyPairMigrated,
w.ens
)

View File

@ -1,22 +1,29 @@
import io_interface import io_interface
import ../../../../app_service/service/settings/service as settings_service import ../../../../app_service/service/settings/service as settings_service
import ../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/currency/service as currency_service
import ../../shared_models/currency_amount
import ../../shared_models/currency_amount_utils
type type
Controller* = ref object of RootObj Controller* = ref object of RootObj
delegate: io_interface.AccessInterface delegate: io_interface.AccessInterface
settingsService: settings_service.Service settingsService: settings_service.Service
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
currencyService: currency_service.Service
proc newController*( proc newController*(
delegate: io_interface.AccessInterface, delegate: io_interface.AccessInterface,
settingsService: settings_service.Service, settingsService: settings_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
currencyService: currency_service.Service,
): Controller = ): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.settingsService = settingsService result.settingsService = settingsService
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.currencyService = currencyService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -33,8 +40,8 @@ proc getSigningPhrase*(self: Controller): string =
proc isMnemonicBackedUp*(self: Controller): bool = proc isMnemonicBackedUp*(self: Controller): bool =
return self.settingsService.getMnemonic().len > 0 return self.settingsService.getMnemonic().len > 0
proc getCurrencyBalance*(self: Controller): float64 = proc getCurrencyBalance*(self: Controller): CurrencyAmount =
return self.walletAccountService.getTotalCurrencyBalance() return currencyAmountToItem(self.walletAccountService.getTotalCurrencyBalance(), self.currencyService.getCurrencyFormat(self.getCurrency()))
proc updateCurrency*(self: Controller, currency: string) = proc updateCurrency*(self: Controller, currency: string) =
self.walletAccountService.updateCurrency(currency) self.walletAccountService.updateCurrency(currency)

View File

@ -1,24 +1,31 @@
import sugar, sequtils import sugar, sequtils, Tables
import io_interface import io_interface
import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../../../app_service/service/token/service as token_service
import ../../../../../app_service/service/currency/service as currency_service
type type
Controller* = ref object of RootObj Controller* = ref object of RootObj
delegate: io_interface.AccessInterface delegate: io_interface.AccessInterface
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
networkService: network_service.Service networkService: network_service.Service
tokenService: token_service.Service
currencyService: currency_service.Service
proc newController*( proc newController*(
delegate: io_interface.AccessInterface, delegate: io_interface.AccessInterface,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service,
): Controller = ): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.networkService = networkService result.networkService = networkService
result.tokenService = tokenService
result.currencyService = currencyService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -39,4 +46,13 @@ proc getChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().map(n => n.chainId) return self.networkService.getNetworks().map(n => n.chainId)
proc getEnabledChainIds*(self: Controller): seq[int] = proc getEnabledChainIds*(self: Controller): seq[int] =
return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId) return self.networkService.getNetworks().filter(n => n.enabled).map(n => n.chainId)
proc getCurrentCurrency*(self: Controller): string =
return self.walletAccountService.getCurrency()
proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
return self.currencyService.getCurrencyFormat(symbol)
proc getAllMigratedKeyPairs*(self: Controller): seq[KeyPairDto] =
return self.walletAccountService.getAllMigratedKeyPairs()

View File

@ -1,11 +1,18 @@
import NimQml, Tables, sequtils import NimQml, Tables, sequtils, sugar
import ../../../../global/global_singleton import ../../../../global/global_singleton
import ../../../../core/eventemitter import ../../../../core/eventemitter
import ../../../../../app_service/service/token/service as token_service
import ../../../../../app_service/service/currency/service as currency_service
import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../app_service/service/network/service as network_service import ../../../../../app_service/service/network/service as network_service
import ../../../shared_models/currency_amount_utils
import ../../../shared_models/token_model as token_model import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item import ../../../shared_models/token_item as token_item
import ../../../shared_models/token_utils
import ../accounts/compact_item as account_compact_item
import ../accounts/item as account_item
import ../accounts/utils
import ./io_interface, ./view, ./controller import ./io_interface, ./view, ./controller
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
@ -28,13 +35,15 @@ proc newModule*(
events: EventEmitter, events: EventEmitter,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
networkService: network_service.Service, networkService: network_service.Service,
tokenService: token_service.Service,
currencyService: currency_service.Service,
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.events = events result.events = events
result.currentAccountIndex = 0 result.currentAccountIndex = 0
result.view = newView(result) result.view = newView(result)
result.controller = newController(result, walletAccountService, networkService) result.controller = newController(result, walletAccountService, networkService, tokenService, currencyService)
result.moduleLoaded = false result.moduleLoaded = false
method delete*(self: Module) = method delete*(self: Module) =
@ -71,49 +80,68 @@ method viewDidLoad*(self: Module) =
self.delegate.currentAccountModuleDidLoad() self.delegate.currentAccountModuleDidLoad()
proc setAssetsAndBalance(self: Module, tokens: seq[WalletTokenDto]) = proc setAssetsAndBalance(self: Module, tokens: seq[WalletTokenDto]) =
var totalCurrencyBalanceForAllAssets = 0.0
let chainIds = self.controller.getChainIds() let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds() let enabledChainIds = self.controller.getEnabledChainIds()
var items: seq[Item] let currency = self.controller.getCurrentCurrency()
for t in tokens:
let item = token_item.initItem( let currencyFormat = self.controller.getCurrencyFormat(currency)
t.name,
t.symbol, let items = tokens.map(t => walletTokenToItem(t, chainIds, enabledChainIds, currency, currencyFormat, self.controller.getCurrencyFormat(t.symbol)))
t.getBalance(chainIds),
t.getCurrencyBalance(chainIds), let totalCurrencyBalanceForAllAssets = tokens.map(t => t.getCurrencyBalance(enabledChainIds, currency)).foldl(a + b, 0.0)
t.getBalance(enabledChainIds),
t.getCurrencyBalance(enabledChainIds),
t.getVisibleForNetwork(enabledChainIds),
t.getVisibleForNetworkWithPositiveBalance(enabledChainIds),
t.getBalances(enabledChainIds),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.getAddress(),
t.marketCap,
t.highDay,
t.lowDay,
t.changePctHour,
t.changePctDay,
t.changePct24hour,
t.change24hour,
t.currencyPrice,
t.decimals,
)
items.add(item)
totalCurrencyBalanceForAllAssets += t.getCurrencyBalance(enabledChainIds)
self.view.getAssetsModel().setItems(items) self.view.getAssetsModel().setItems(items)
self.view.setCurrencyBalance(totalCurrencyBalanceForAllAssets) self.view.setCurrencyBalance(currencyAmountToItem(totalCurrencyBalanceForAllAssets, currencyFormat))
method switchAccount*(self: Module, accountIndex: int) = method switchAccount*(self: Module, accountIndex: int) =
self.currentAccountIndex = accountIndex self.currentAccountIndex = accountIndex
let enabledChainIds = self.controller.getEnabledChainIds()
let keyPairMigrated = proc(migratedKeyPairs: seq[KeyPairDto], keyUid: string): bool =
for kp in migratedKeyPairs:
if kp.keyUid == keyUid:
return true
return false
let defaultAccount = self.controller.getWalletAccount(0) # can safely do this as the account will always contain atleast one account
let walletAccount = self.controller.getWalletAccount(accountIndex) 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)) let migratedKeyPairs = self.controller.getAllMigratedKeyPairs()
self.view.setData(walletAccount, enabledChainIds) let currency = self.controller.getCurrentCurrency()
let chainIds = self.controller.getChainIds()
let enabledChainIds = self.controller.getEnabledChainIds()
let defaultAccountTokenFormats = collect(initTable()):
for t in defaultAccount.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
let accountTokenFormats = collect(initTable()):
for t in walletAccount.tokens: {t.symbol: self.controller.getCurrencyFormat(t.symbol)}
let currencyFormat = self.controller.getCurrencyFormat(currency)
let defaultAccountItem = walletAccountToItem(
defaultAccount,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, defaultAccount.keyUid),
currencyFormat,
defaultAccountTokenFormats
)
let accountItem = walletAccountToItem(
walletAccount,
chainIds,
enabledChainIds,
currency,
keyPairMigrated(migratedKeyPairs, walletAccount.keyUid),
currencyFormat,
accountTokenFormats
)
self.view.setDefaultWalletAccount(defaultAccountItem)
self.view.setData(accountItem)
self.setAssetsAndBalance(walletAccount.tokens) self.setAssetsAndBalance(walletAccount.tokens)
method update*(self: Module, address: string, accountName: string, color: string, emoji: string) = method update*(self: Module, address: string, accountName: string, color: string, emoji: string) =

View File

@ -1,12 +1,14 @@
import NimQml, sequtils, sugar import NimQml, sequtils, sugar, json
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
import ./io_interface import ./io_interface
import ../../../shared_models/token_model as token_model import ../../../shared_models/token_model as token_model
import ../../../shared_models/token_item as token_item import ../../../shared_models/token_item as token_item
import ../../../shared_models/currency_amount
import ../accounts/compact_model import ../accounts/compact_model
import ../accounts/compact_item import ../accounts/compact_item
import ../accounts/item as account_item
const GENERATED = "generated" const GENERATED = "generated"
const GENERATED_FROM_IMPORTED = "generated from imported accounts" const GENERATED_FROM_IMPORTED = "generated from imported accounts"
@ -14,7 +16,7 @@ QtObject:
type type
View* = ref object of QObject View* = ref object of QObject
delegate: io_interface.AccessInterface delegate: io_interface.AccessInterface
defaultAccount: wallet_account_service.WalletAccountDto defaultAccount: account_item.Item
name: string name: string
address: string address: string
mixedcaseAddress: string mixedcaseAddress: string
@ -23,7 +25,7 @@ QtObject:
publicKey: string publicKey: string
walletType: string walletType: string
isChat: bool isChat: bool
currencyBalance: float64 currencyBalance: CurrencyAmount
assets: token_model.Model assets: token_model.Model
emoji: string emoji: string
derivedfrom: string derivedfrom: string
@ -117,7 +119,7 @@ QtObject:
proc currencyBalanceChanged(self: View) {.signal.} proc currencyBalanceChanged(self: View) {.signal.}
proc getCurrencyBalance*(self: View): QVariant {.slot.} = proc getCurrencyBalance*(self: View): QVariant {.slot.} =
return newQVariant(self.currencyBalance) return newQVariant(self.currencyBalance)
proc setCurrencyBalance*(self: View, value: float) = proc setCurrencyBalance*(self: View, value: CurrencyAmount) =
self.currencyBalance = value self.currencyBalance = value
self.currencyBalanceChanged() self.currencyBalanceChanged()
QtProperty[QVariant] currencyBalance: QtProperty[QVariant] currencyBalance:
@ -173,66 +175,50 @@ QtObject:
proc update(self: View, address: string, accountName: string, color: string, emoji: string) {.slot.} = proc update(self: View, address: string, accountName: string, color: string, emoji: string) {.slot.} =
self.delegate.update(address, accountName, color, emoji) self.delegate.update(address, accountName, color, emoji)
proc setDefaultWalletAccount*(self: View, default: wallet_account_service.WalletAccountDto) = proc setDefaultWalletAccount*(self: View, default: account_item.Item) =
self.defaultAccount = default self.defaultAccount = default
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto, chainIds: seq[int]) = proc setData*(self: View, item: account_item.Item) =
if(self.name != dto.name): if(self.name != item.getName()):
self.name = dto.name self.name = item.getName()
self.nameChanged() self.nameChanged()
if(self.address != dto.address): if(self.address != item.getAddress()):
self.address = dto.address self.address = item.getAddress()
self.addressChanged() self.addressChanged()
if(self.mixedcaseAddress != dto.mixedcaseAddress): if(self.mixedcaseAddress != item.getMixedCaseAddress()):
self.mixedcaseAddress = dto.mixedcaseAddress self.mixedcaseAddress = item.getMixedCaseAddress()
self.mixedcaseAddressChanged() self.mixedcaseAddressChanged()
if(self.path != dto.path): if(self.path != item.getPath()):
self.path = dto.path self.path = item.getPath()
self.pathChanged() self.pathChanged()
if(self.color != dto.color): if(self.color != item.getColor()):
self.color = dto.color self.color = item.getColor()
self.colorChanged() self.colorChanged()
if(self.publicKey != dto.publicKey): if(self.publicKey != item.getPublicKey()):
self.publicKey = dto.publicKey self.publicKey = item.getPublicKey()
self.publicKeyChanged() self.publicKeyChanged()
# Check if the account is generated from default wallet account else change wallettype # Check if the account is generated from default wallet account else change wallettype
if dto.walletType == GENERATED and dto.derivedfrom != self.defaultAccount.derivedfrom: if item.getWalletType() == GENERATED and item.getDerivedfrom() != self.defaultAccount.getDerivedfrom():
self.walletType = GENERATED_FROM_IMPORTED self.walletType = GENERATED_FROM_IMPORTED
self.walletTypeChanged() self.walletTypeChanged()
else: else:
if(self.walletType != dto.walletType): if(self.walletType != item.getWalletType()):
self.walletType = dto.walletType self.walletType = item.getWalletType()
self.walletTypeChanged() self.walletTypeChanged()
if(self.isChat != dto.isChat): if(self.isChat != item.getIsChat()):
self.isChat = dto.isChat self.isChat = item.getIsChat()
self.isChatChanged() self.isChatChanged()
if(self.emoji != dto.emoji): if(self.emoji != item.getEmoji()):
self.emoji = dto.emoji self.emoji = item.getEmoji()
self.emojiChanged() self.emojiChanged()
if(self.derivedfrom != dto.derivedfrom): if(self.derivedfrom != item.getDerivedFrom()):
self.derivedfrom = dto.derivedfrom self.derivedfrom = item.getDerivedFrom()
self.derivedfromChanged() self.derivedfromChanged()
if(self.ens != dto.ens): if(self.ens != item.getEns()):
self.ens = dto.ens self.ens = item.getEns()
self.ensChanged() self.ensChanged()
# Set related accounts # Set related accounts
let relatedAccounts = compact_model.newModel() self.relatedAccounts = item.getRelatedAccounts()
relatedAccounts.setItems(
dto.relatedAccounts.map(x => compact_item.initItem(
x.name,
x.address,
x.path,
x.color,
x.publicKey,
x.walletType,
x.isWallet,
x.isChat,
x.getCurrencyBalance(chainIds),
x.emoji,
x.derivedfrom
))
)
self.relatedAccounts = relatedAccounts
self.relatedAccountsChanged() self.relatedAccountsChanged()
proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} = proc findTokenSymbolByAddress*(self: View, address: string): string {.slot.} =
@ -241,5 +227,9 @@ QtObject:
proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} = proc hasGas*(self: View, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.slot.} =
return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas) return self.assets.hasGas(chainId, nativeGasSymbol, requiredGas)
proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): string {.slot.} = # Returning a QVariant from a slot with parameters other than "self" won't compile
return self.assets.getTokenBalanceOnChain(chainId, tokenSymbol) #proc getTokenBalanceOnChain*(self: View, chainId: int, tokenSymbol: string): QVariant {.slot.} =
# return newQVariant(self.assets.getTokenBalanceOnChain(chainId, tokenSymbol))
proc getTokenBalanceOnChainAsJson*(self: View, chainId: int, tokenSymbol: string): string {.slot.} =
return $self.assets.getTokenBalanceOnChain(chainId, tokenSymbol).toJsonNode()

View File

@ -16,6 +16,7 @@ import ../../../global/global_singleton
import ../../../core/eventemitter import ../../../core/eventemitter
import ../../../../app_service/service/keycard/service as keycard_service import ../../../../app_service/service/keycard/service as keycard_service
import ../../../../app_service/service/token/service as token_service import ../../../../app_service/service/token/service as token_service
import ../../../../app_service/service/currency/service as currency_service
import ../../../../app_service/service/transaction/service as transaction_service import ../../../../app_service/service/transaction/service as transaction_service
import ../../../../app_service/service/collectible/service as collectible_service import ../../../../app_service/service/collectible/service as collectible_service
import ../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../app_service/service/wallet_account/service as wallet_account_service
@ -48,6 +49,7 @@ proc newModule*(
delegate: delegate_interface.AccessInterface, delegate: delegate_interface.AccessInterface,
events: EventEmitter, events: EventEmitter,
tokenService: token_service.Service, tokenService: token_service.Service,
currencyService: currency_service.Service,
transactionService: transaction_service.Service, transactionService: transaction_service.Service,
collectibleService: collectible_service.Service, collectibleService: collectible_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
@ -61,13 +63,13 @@ proc newModule*(
result.delegate = delegate result.delegate = delegate
result.events = events result.events = events
result.moduleLoaded = false result.moduleLoaded = false
result.controller = newController(result, settingsService, walletAccountService) result.controller = newController(result, settingsService, walletAccountService, currencyService)
result.view = newView(result) result.view = newView(result)
result.accountsModule = accounts_module.newModule(result, events, keycardService, walletAccountService, accountsService, networkService) result.accountsModule = accounts_module.newModule(result, events, keycardService, walletAccountService, accountsService, networkService, tokenService, currencyService)
result.allTokensModule = all_tokens_module.newModule(result, events, tokenService, walletAccountService) result.allTokensModule = all_tokens_module.newModule(result, events, tokenService, walletAccountService)
result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService, networkService) result.collectiblesModule = collectibles_module.newModule(result, events, collectibleService, walletAccountService, networkService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService) result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService, networkService, tokenService, currencyService)
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService, networkService) result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService, networkService)
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService) result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService) result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)

View File

@ -1,13 +1,14 @@
import NimQml import NimQml
import ./io_interface import ./io_interface
import ../../shared_models/currency_amount
QtObject: QtObject:
type type
View* = ref object of QObject View* = ref object of QObject
delegate: io_interface.AccessInterface delegate: io_interface.AccessInterface
currentCurrency: string currentCurrency: string
totalCurrencyBalance: float64 totalCurrencyBalance: CurrencyAmount
signingPhrase: string signingPhrase: string
isMnemonicBackedUp: bool isMnemonicBackedUp: bool
@ -66,7 +67,7 @@ QtObject:
proc switchAccountByAddress(self: View, address: string) {.slot.} = proc switchAccountByAddress(self: View, address: string) {.slot.} =
self.delegate.switchAccountByAddress(address) self.delegate.switchAccountByAddress(address)
proc setTotalCurrencyBalance*(self: View, totalCurrencyBalance: float64) = proc setTotalCurrencyBalance*(self: View, totalCurrencyBalance: CurrencyAmount) =
self.totalCurrencyBalance = totalCurrencyBalance self.totalCurrencyBalance = totalCurrencyBalance
self.totalCurrencyBalanceChanged() self.totalCurrencyBalanceChanged()

View File

@ -0,0 +1,42 @@
import strformat
import ./currency_amount
type
Item* = object
balance*: CurrencyAmount
address*: string
chainId*: int
proc initItem*(
balance: CurrencyAmount,
address: string,
chainId: int,
): Item =
result.balance = balance
result.address = address
result.chainId = chainId
proc `$`*(self: Item): string =
result = fmt"""BalanceItem(
name: {self.balance},
address: {self.address},
chainId: {self.chainId},
]"""
proc getBalance*(self: Item): CurrencyAmount =
return self.balance
proc getAddress*(self: Item): string =
return self.address
proc getChainId*(self: Item): int =
return self.chainId
proc getCurrencyBalance*(self: Item, currencyPrice: CurrencyAmount): CurrencyAmount =
return newCurrencyAmount(
self.balance.getAmount() * currencyPrice.getAmount(),
currencyPrice.getSymbol(),
currencyPrice.getDisplayDecimals(),
currencyPrice.isStripTrailingZeroesActive()
)

View File

@ -1,6 +1,7 @@
import NimQml, Tables, strutils, strformat import NimQml, Tables, strutils, strformat
import ../../../app_service/service/wallet_account/dto import balance_item
import ./currency_amount
type type
ModelRole {.pure.} = enum ModelRole {.pure.} = enum
@ -11,7 +12,7 @@ type
QtObject: QtObject:
type type
BalanceModel* = ref object of QAbstractListModel BalanceModel* = ref object of QAbstractListModel
items*: seq[BalanceDto] items*: seq[Item]
proc delete(self: BalanceModel) = proc delete(self: BalanceModel) =
self.items = @[] self.items = @[]
@ -63,7 +64,7 @@ QtObject:
of ModelRole.Address: of ModelRole.Address:
result = newQVariant(item.address) result = newQVariant(item.address)
of ModelRole.Balance: of ModelRole.Balance:
result = newQVariant($item.balance) result = newQVariant(item.balance)
proc rowData(self: BalanceModel, index: int, column: string): string {.slot.} = proc rowData(self: BalanceModel, index: int, column: string): string {.slot.} =
if (index >= self.items.len): if (index >= self.items.len):
@ -74,7 +75,7 @@ QtObject:
of "address": result = $item.address of "address": result = $item.address
of "balance": result = $item.balance of "balance": result = $item.balance
proc setItems*(self: BalanceModel, items: seq[BalanceDto]) = proc setItems*(self: BalanceModel, items: seq[Item]) =
self.beginResetModel() self.beginResetModel()
self.items = items self.items = items
self.endResetModel() self.endResetModel()

View File

@ -0,0 +1,11 @@
import ../../../app_service/service/wallet_account/dto
import ../../../app_service/service/currency/dto as currency_dto
import ./currency_amount_utils
import ./balance_item
proc balanceToItem*(b: BalanceDto, format: CurrencyFormatDto) : Item =
return initItem(
currencyAmountToItem(b.balance, format),
b.address,
b.chainId
)

View File

@ -0,0 +1,67 @@
import NimQml, strformat, json
QtObject:
type CurrencyAmount* = ref object of QObject
amount: float64
symbol: string
displayDecimals: int
stripTrailingZeroes: bool
proc setup(self: CurrencyAmount) =
self.QObject.setup
proc delete*(self: CurrencyAmount) =
self.QObject.delete
proc newCurrencyAmount*(
amount: float64,
symbol: string,
displayDecimals: int,
stripTrailingZeroes: bool,
): CurrencyAmount =
new(result, delete)
result.setup
result.amount = amount
result.symbol = symbol
result.displayDecimals = displayDecimals
result.stripTrailingZeroes = stripTrailingZeroes
proc `$`*(self: CurrencyAmount): string =
result = fmt"""CurrencyAmount(
amount: {self.amount},
symbol: {self.symbol},
displayDecimals: {self.displayDecimals},
stripTrailingZeroes: {self.stripTrailingZeroes}
)"""
proc getAmount*(self: CurrencyAmount): float64 =
return self.amount
proc getAmountFloat*(self: CurrencyAmount): float {.slot.} =
return self.amount
QtProperty[float] amount:
read = getAmountFloat
proc getSymbol*(self: CurrencyAmount): string {.slot.} =
return self.symbol
QtProperty[string] symbol:
read = getSymbol
proc getDisplayDecimals*(self: CurrencyAmount): int {.slot.} =
return self.displayDecimals
QtProperty[int] displayDecimals:
read = getDisplayDecimals
proc isStripTrailingZeroesActive*(self: CurrencyAmount): bool {.slot.} =
return self.stripTrailingZeroes
QtProperty[bool] stripTrailingZeroes:
read = isStripTrailingZeroesActive
# Needed to expose object to QML, see issue #8913
proc toJsonNode*(self: CurrencyAmount): JsonNode =
result = %* {
"amount": self.amount,
"symbol": self.symbol,
"displayDecimals": self.displayDecimals,
"stripTrailingZeroes": self.stripTrailingZeroes
}

View File

@ -0,0 +1,10 @@
import ../../../app_service/service/currency/dto
import ./currency_amount
proc currencyAmountToItem*(amount: float64, format: CurrencyFormatDto) : CurrencyAmount =
return newCurrencyAmount(
amount,
format.symbol,
format.displayDecimals,
format.stripTrailingZeroes
)

View File

@ -1,16 +1,18 @@
import strformat import strformat
import ../../../app_service/service/wallet_account/dto import ../../../app_service/service/wallet_account/dto
import ./balance_item as balance_item
import ./balance_model as balance_model import ./balance_model as balance_model
import ./currency_amount
type type
Item* = object Item* = object
name: string name: string
symbol: string symbol: string
totalBalance: float totalBalance: CurrencyAmount
totalCurrencyBalance: float totalCurrencyBalance: CurrencyAmount
enabledNetworkCurrencyBalance: float enabledNetworkCurrencyBalance: CurrencyAmount
enabledNetworkBalance: float enabledNetworkBalance: CurrencyAmount
visibleForNetwork: bool visibleForNetwork: bool
visibleForNetworkWithPositiveBalance: bool visibleForNetworkWithPositiveBalance: bool
balances: balance_model.BalanceModel balances: balance_model.BalanceModel
@ -18,38 +20,40 @@ type
assetWebsiteUrl: string assetWebsiteUrl: string
builtOn: string builtOn: string
address: string address: string
marketCap: string marketCap: CurrencyAmount
highDay: string highDay: CurrencyAmount
lowDay: string lowDay: CurrencyAmount
changePctHour: string changePctHour: float64
changePctDay: string changePctDay: float64
changePct24hour: string changePct24hour: float64
change24hour: string change24hour: float64
currencyPrice: float currencyPrice: CurrencyAmount
decimals: int decimals: int
pegSymbol: string
proc initItem*( proc initItem*(
name, symbol: string, name, symbol: string,
totalBalance: float, totalBalance: CurrencyAmount,
totalCurrencyBalance: float, totalCurrencyBalance: CurrencyAmount,
enabledNetworkBalance: float, enabledNetworkBalance: CurrencyAmount,
enabledNetworkCurrencyBalance: float, enabledNetworkCurrencyBalance: CurrencyAmount,
visibleForNetwork: bool, visibleForNetwork: bool,
visibleForNetworkWithPositiveBalance: bool, visibleForNetworkWithPositiveBalance: bool,
balances: seq[BalanceDto], balances: seq[balance_item.Item],
description: string, description: string,
assetWebsiteUrl: string, assetWebsiteUrl: string,
builtOn: string, builtOn: string,
address: string, address: string,
marketCap: string, marketCap: CurrencyAmount,
highDay: string, highDay: CurrencyAmount,
lowDay: string, lowDay: CurrencyAmount,
changePctHour: string, changePctHour: float64,
changePctDay: string, changePctDay: float64,
changePct24hour: string, changePct24hour: float64,
change24hour: string, change24hour: float64,
currencyPrice: float, currencyPrice: CurrencyAmount,
decimals: int, decimals: int,
pegSymbol: string,
): Item = ): Item =
result.name = name result.name = name
result.symbol = symbol result.symbol = symbol
@ -74,6 +78,7 @@ proc initItem*(
result.change24hour = change24hour result.change24hour = change24hour
result.currencyPrice = currencyPrice result.currencyPrice = currencyPrice
result.decimals = decimals result.decimals = decimals
result.pegSymbol = pegSymbol
proc `$`*(self: Item): string = proc `$`*(self: Item): string =
result = fmt"""AllTokensItem( result = fmt"""AllTokensItem(
@ -98,6 +103,7 @@ proc `$`*(self: Item): string =
change24hour: {self.change24hour}, change24hour: {self.change24hour},
currencyPrice: {self.currencyPrice}, currencyPrice: {self.currencyPrice},
decimals: {self.decimals}, decimals: {self.decimals},
pegSymbol: {self.pegSymbol},
]""" ]"""
proc getName*(self: Item): string = proc getName*(self: Item): string =
@ -106,16 +112,16 @@ proc getName*(self: Item): string =
proc getSymbol*(self: Item): string = proc getSymbol*(self: Item): string =
return self.symbol return self.symbol
proc getTotalBalance*(self: Item): float = proc getTotalBalance*(self: Item): CurrencyAmount =
return self.totalBalance return self.totalBalance
proc getTotalCurrencyBalance*(self: Item): float = proc getTotalCurrencyBalance*(self: Item): CurrencyAmount =
return self.totalCurrencyBalance return self.totalCurrencyBalance
proc getEnabledNetworkBalance*(self: Item): float = proc getEnabledNetworkBalance*(self: Item): CurrencyAmount =
return self.enabledNetworkBalance return self.enabledNetworkBalance
proc getEnabledNetworkCurrencyBalance*(self: Item): float = proc getEnabledNetworkCurrencyBalance*(self: Item): CurrencyAmount =
return self.enabledNetworkCurrencyBalance return self.enabledNetworkCurrencyBalance
proc getVisibleForNetwork*(self: Item): bool = proc getVisibleForNetwork*(self: Item): bool =
@ -139,29 +145,32 @@ proc getBuiltOn*(self: Item): string =
proc getAddress*(self: Item): string = proc getAddress*(self: Item): string =
return self.address return self.address
proc getMarketCap*(self: Item): string = proc getMarketCap*(self: Item): CurrencyAmount =
return self.marketCap return self.marketCap
proc getHighDay*(self: Item): string = proc getHighDay*(self: Item): CurrencyAmount =
return self.highDay return self.highDay
proc getLowDay*(self: Item): string = proc getLowDay*(self: Item): CurrencyAmount =
return self.lowDay return self.lowDay
proc getChangePctHour*(self: Item): string = proc getChangePctHour*(self: Item): float64 =
return self.changePctHour return self.changePctHour
proc getChangePctDay*(self: Item): string = proc getChangePctDay*(self: Item): float64 =
return self.changePctDay return self.changePctDay
proc getChangePct24hour*(self: Item): string = proc getChangePct24hour*(self: Item): float64 =
return self.changePct24hour return self.changePct24hour
proc getChange24hour*(self: Item): string = proc getChange24hour*(self: Item): float64 =
return self.change24hour return self.change24hour
proc getCurrencyPrice*(self: Item): float = proc getCurrencyPrice*(self: Item): CurrencyAmount =
return self.currencyPrice return self.currencyPrice
proc getDecimals*(self: Item): int = proc getDecimals*(self: Item): int =
return self.decimals return self.decimals
proc getPegSymbol*(self: Item): string =
return self.pegSymbol

View File

@ -1,6 +1,7 @@
import NimQml, Tables, strutils, strformat import NimQml, Tables, strutils, strformat
import ./token_item import ./token_item
import ./currency_amount
type type
ModelRole {.pure.} = enum ModelRole {.pure.} = enum
@ -26,6 +27,7 @@ type
Change24hour Change24hour
CurrencyPrice CurrencyPrice
Decimals Decimals
PegSymbol
QtObject: QtObject:
type type
@ -83,6 +85,7 @@ QtObject:
ModelRole.Change24hour.int:"change24hour", ModelRole.Change24hour.int:"change24hour",
ModelRole.CurrencyPrice.int:"currencyPrice", ModelRole.CurrencyPrice.int:"currencyPrice",
ModelRole.Decimals.int:"decimals", ModelRole.Decimals.int:"decimals",
ModelRole.PegSymbol.int:"pegSymbol",
}.toTable }.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant = method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -140,6 +143,8 @@ QtObject:
result = newQVariant(item.getCurrencyPrice()) result = newQVariant(item.getCurrencyPrice())
of ModelRole.Decimals: of ModelRole.Decimals:
result = newQVariant(item.getDecimals()) result = newQVariant(item.getDecimals())
of ModelRole.PegSymbol:
result = newQVariant(item.getPegSymbol())
proc rowData(self: Model, index: int, column: string): string {.slot.} = proc rowData(self: Model, index: int, column: string): string {.slot.} =
if (index >= self.items.len): if (index >= self.items.len):
@ -167,6 +172,7 @@ QtObject:
of "change24hour": result = $item.getChange24hour() of "change24hour": result = $item.getChange24hour()
of "currencyPrice": result = $item.getCurrencyPrice() of "currencyPrice": result = $item.getCurrencyPrice()
of "decimals": result = $item.getDecimals() of "decimals": result = $item.getDecimals()
of "pegSymbol": result = $item.getPegSymbol()
proc setItems*(self: Model, items: seq[Item]) = proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel() self.beginResetModel()
@ -191,13 +197,12 @@ QtObject:
if (balance.chainId != chainId): if (balance.chainId != chainId):
continue continue
if(balance.balance >= requiredGas): if(balance.balance.getAmount() >= requiredGas):
return true return true
return false return false
proc getTokenBalanceOnChain*(self: Model, chainId: int, tokenSymbol: string): string = proc getTokenBalanceOnChain*(self: Model, chainId: int, tokenSymbol: string): CurrencyAmount =
var tokenBalance: float64 = 0.0
for item in self.items: for item in self.items:
if(item.getSymbol() != tokenSymbol): if(item.getSymbol() != tokenSymbol):
continue continue
@ -206,6 +211,11 @@ QtObject:
if (balance.chainId != chainId): if (balance.chainId != chainId):
continue continue
tokenBalance = balance.balance return balance.balance
return $tokenBalance return newCurrencyAmount(
0.0,
tokenSymbol,
0,
false
)

View File

@ -0,0 +1,42 @@
import tables, sequtils, sugar
import ../../../app_service/service/wallet_account/dto
import ../../../app_service/service/currency/dto as currency_dto
import ./currency_amount_utils
import ./balance_utils
import ./token_item
proc walletTokenToItem*(
t: WalletTokenDto,
chainIds: seq[int],
enabledChainIds: seq[int],
currency: string,
currencyFormat: CurrencyFormatDto,
tokenFormat: CurrencyFormatDto,
) : token_item.Item =
let marketValues = t.marketValuesPerCurrency.getOrDefault(currency)
return token_item.initItem(
t.name,
t.symbol,
currencyAmountToItem(t.getBalance(chainIds), tokenFormat),
currencyAmountToItem(t.getCurrencyBalance(chainIds, currency), currencyFormat),
currencyAmountToItem(t.getBalance(enabledChainIds), tokenFormat),
currencyAmountToItem(t.getCurrencyBalance(enabledChainIds, currency), currencyFormat),
t.getVisibleForNetwork(enabledChainIds),
t.getVisibleForNetworkWithPositiveBalance(enabledChainIds),
t.getBalances(enabledChainIds).map(b => balanceToItem(b, tokenFormat)),
t.description,
t.assetWebsiteUrl,
t.builtOn,
t.getAddress(),
currencyAmountToItem(marketValues.marketCap, currencyFormat),
currencyAmountToItem(marketValues.highDay, currencyFormat),
currencyAmountToItem(marketValues.lowDay, currencyFormat),
marketValues.changePctHour,
marketValues.changePctDay,
marketValues.changePct24hour,
marketValues.change24hour,
currencyAmountToItem(marketValues.price, currencyFormat),
t.decimals,
t.pegSymbol
)

View File

@ -0,0 +1,6 @@
type
CurrencyFormatDto* = ref object
symbol*: string
displayDecimals*: int
stripTrailingZeroes*: bool

View File

@ -0,0 +1,55 @@
import NimQml, strformat, strutils
import ../settings/service as settings_service
import ../token/service as token_service
import ./dto, ./utils
export dto
const DECIMALS_CALCULATION_CURRENCY = "USD"
QtObject:
type Service* = ref object of QObject
tokenService: token_service.Service
settingsService: settings_service.Service
proc delete*(self: Service) =
self.QObject.delete
proc newService*(
tokenService: token_service.Service,
settingsService: settings_service.Service,
): Service =
new(result, delete)
result.QObject.setup
result.tokenService = tokenService
result.settingsService = settingsService
proc init*(self: Service) =
discard
proc getFiatCurrencyFormat(self: Service, symbol: string): CurrencyFormatDto =
return CurrencyFormatDto(
symbol: toUpperAscii(symbol),
displayDecimals: getFiatDisplayDecimals(symbol),
stripTrailingZeroes: false
)
proc getTokenCurrencyFormat(self: Service, symbol: string): CurrencyFormatDto =
let pegSymbol = self.tokenService.getTokenPegSymbol(symbol)
if pegSymbol != "":
var currencyFormat = self.getFiatCurrencyFormat(pegSymbol)
currencyFormat.symbol = symbol
return currencyFormat
else:
let price = self.tokenService.getTokenPrice(symbol, DECIMALS_CALCULATION_CURRENCY, false)
return CurrencyFormatDto(
symbol: symbol,
displayDecimals: getTokenDisplayDecimals(price),
stripTrailingZeroes: true
)
proc getCurrencyFormat*(self: Service, symbol: string): CurrencyFormatDto =
if isCurrencyFiat(symbol):
return self.getFiatCurrencyFormat(symbol)
else:
return self.getTokenCurrencyFormat(symbol)

View File

@ -0,0 +1,33 @@
import math, chronicles, json, strutils
import ../../../backend/backend as backend
logScope:
topics = "currency-utils"
proc isCurrencyFiat*(symbol: string): bool =
let response = backend.isCurrencyFiat(symbol)
return response.result.getBool
proc getFiatDisplayDecimals*(symbol: string): int =
result = 0
try:
let response = backend.getFiatCurrencyMinorUnit(symbol)
result = response.result.getInt
except Exception as e:
let errDesription = e.msg
error "error getFiatDisplayDecimals: ", errDesription
proc getTokenDisplayDecimals*(currencyPrice: float): int =
var decimals = 0.0
if currencyPrice > 0:
const lowerCurrencyResolution = 0.1
const higherCurrencyResolution = 0.01
let lowerDecimalsBound = max(0.0, log10(currencyPrice) - log10(lowerCurrencyResolution))
let upperDecimalsBound = max(0.0, log10(currencyPrice) - log10(higherCurrencyResolution))
# Use as few decimals as needed to ensure lower precision
decimals = ceil(lowerDecimalsBound)
if (decimals + 1 < upperDecimalsBound):
# If allowed by upper bound, ensure resolution changes as soon as currency hits multiple of 10
decimals += 1
return decimals.int

View File

@ -318,7 +318,7 @@ QtObject:
proc getTransactionDetails*(self: Service, message: MessageDto): (string, string) = proc getTransactionDetails*(self: Service, message: MessageDto): (string, string) =
let networksDto = self.networkService.getNetworks() let networksDto = self.networkService.getNetworks()
var token = newTokenDto(networksDto[0].nativeCurrencyName, networksDto[0].chainId, parseAddress(ZERO_ADDRESS), networksDto[0].nativeCurrencySymbol, networksDto[0].nativeCurrencyDecimals, true) var token = newTokenDto(networksDto[0].nativeCurrencyName, networksDto[0].chainId, parseAddress(ZERO_ADDRESS), networksDto[0].nativeCurrencySymbol, networksDto[0].nativeCurrencyDecimals, true, "")
if message.transactionParameters.contract != "": if message.transactionParameters.contract != "":
for networkDto in networksDto: for networkDto in networksDto:

View File

@ -23,17 +23,7 @@ type
color*: string color*: string
isCustom* {.dontSerialize.}: bool isCustom* {.dontSerialize.}: bool
isVisible* {.dontSerialize.}: bool isVisible* {.dontSerialize.}: bool
description* :string pegSymbol*: string
assetWebsiteUrl*: string
builtOn*: string
smartContractAddress*: string
marketCap*: string
highDay*: string
lowDay*: string
changePctHour*: string
changePctDay*: string
changePct24hour*: string
change24hour*: string
proc newTokenDto*( proc newTokenDto*(
name: string, name: string,
@ -42,18 +32,8 @@ proc newTokenDto*(
symbol: string, symbol: string,
decimals: int, decimals: int,
hasIcon: bool, hasIcon: bool,
pegSymbol: string,
isCustom: bool = false, isCustom: bool = false,
description: string = "",
assetWebsiteUrl: string = "",
builtOn: string = "",
smartContractAddress: string = "",
marketCap: string = "",
highDay: string = "",
lowDay: string = "",
changePctHour: string = "",
changePctDay: string = "",
changePct24hour: string = "",
change24hour: string = "",
): TokenDto = ): TokenDto =
return TokenDto( return TokenDto(
name: name, name: name,
@ -62,6 +42,7 @@ proc newTokenDto*(
symbol: symbol, symbol: symbol,
decimals: decimals, decimals: decimals,
hasIcon: hasIcon, hasIcon: hasIcon,
pegSymbol: pegSymbol,
isCustom: isCustom isCustom: isCustom
) )
@ -76,6 +57,7 @@ proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCu
discard jsonObj.getProp("symbol", result.symbol) discard jsonObj.getProp("symbol", result.symbol)
discard jsonObj.getProp("decimals", result.decimals) discard jsonObj.getProp("decimals", result.decimals)
discard jsonObj.getProp("color", result.color) discard jsonObj.getProp("color", result.color)
discard jsonObj.getProp("pegSymbol", result.pegSymbol)
result.isVisible = isVisible result.isVisible = isVisible
proc addressAsString*(self: TokenDto): string = proc addressAsString*(self: TokenDto): string =

View File

@ -6,9 +6,12 @@ from web3/conversions import `$`
import ../../../backend/backend as backend import ../../../backend/backend as backend
import ../network/service as network_service import ../network/service as network_service
import ../wallet_account/dto as wallet_account_dto
import ../../../app/global/global_singleton
import ../../../app/core/eventemitter import ../../../app/core/eventemitter
import ../../../app/core/tasks/[qt, threadpool] import ../../../app/core/tasks/[qt, threadpool]
import ../../../backend/cache
import ./dto import ./dto
export dto export dto
@ -36,6 +39,9 @@ QtObject:
threadpool: ThreadPool threadpool: ThreadPool
networkService: network_service.Service networkService: network_service.Service
tokens: Table[int, seq[TokenDto]] tokens: Table[int, seq[TokenDto]]
priceCache: TimedCache
proc updateCachedTokenPrice(self: Service, crypto: string, fiat: string, price: float64)
proc delete*(self: Service) = proc delete*(self: Service) =
self.QObject.delete self.QObject.delete
@ -51,6 +57,7 @@ QtObject:
result.threadpool = threadpool result.threadpool = threadpool
result.networkService = networkService result.networkService = networkService
result.tokens = initTable[int, seq[TokenDto]]() result.tokens = initTable[int, seq[TokenDto]]()
result.priceCache = newTimedCache()
proc init*(self: Service) = proc init*(self: Service) =
try: try:
@ -63,7 +70,6 @@ QtObject:
found = true found = true
break break
if found: if found:
continue continue
@ -82,6 +88,12 @@ QtObject:
error "error: ", errDesription error "error: ", errDesription
return return
proc updateTokenPrices*(self: Service, tokens: seq[WalletTokenDto]) =
# Use data fetched by walletAccountService to update local price cache
for token in tokens:
for currency, marketValues in token.marketValuesPerCurrency:
self.updateCachedTokenPrice(token.symbol, currency, marketValues.price)
proc findTokenBySymbol*(self: Service, network: NetworkDto, symbol: string): TokenDto = proc findTokenBySymbol*(self: Service, network: NetworkDto, symbol: string): TokenDto =
try: try:
for token in self.tokens[network.chainId]: for token in self.tokens[network.chainId]:
@ -111,6 +123,49 @@ QtObject:
return token.symbol return token.symbol
return "" return ""
# Token
proc renameSymbol(symbol: string) : string =
return toUpperAscii(symbol)
proc getTokenPriceCacheKey(crypto: string, fiat: string) : string =
return renameSymbol(crypto) & renameSymbol(fiat)
proc getTokenPrice*(self: Service, crypto: string, fiat: string, fetchIfNotAvailable: bool = true): float64 =
let cacheKey = getTokenPriceCacheKey(crypto, fiat)
if self.priceCache.isCached(cacheKey) or (self.priceCache.hasKey(cacheKey) and not fetchIfNotAvailable):
return parseFloat(self.priceCache.get(cacheKey))
elif not fetchIfNotAvailable:
return 0.0
var prices = initTable[string, Table[string, float]]()
try:
let cryptoKey = renameSymbol(crypto)
let fiatKey = renameSymbol(fiat)
let response = backend.fetchPrices(@[cryptoKey], @[fiatKey])
for (symbol, pricePerCurrency) in response.result.pairs:
for (currency, price) in pricePerCurrency.pairs:
prices[symbol][currency] = price.getFloat
self.updateCachedTokenPrice(cryptoKey, fiatKey, prices[cryptoKey][fiatKey])
return prices[cryptoKey][fiatKey]
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return 0.0
proc updateCachedTokenPrice(self: Service, crypto: string, fiat: string, price: float64) =
let cacheKey = getTokenPriceCacheKey(crypto, fiat)
self.priceCache.set(cacheKey, $price)
proc getTokenPegSymbol*(self: Service, symbol: string): string =
for _, tokens in self.tokens:
for token in tokens:
if token.symbol == symbol:
return token.pegSymbol
return ""
# History Data
proc tokenHistoricalDataResolved*(self: Service, response: string) {.slot.} = proc tokenHistoricalDataResolved*(self: Service, response: string) {.slot.} =
let responseObj = response.parseJson let responseObj = response.parseJson
if (responseObj.kind != JObject): if (responseObj.kind != JObject):
@ -121,17 +176,6 @@ QtObject:
result: response result: response
)) ))
proc tokenBalanceHistoryDataResolved*(self: Service, response: string) {.slot.} =
# TODO
let responseObj = response.parseJson
if (responseObj.kind != JObject):
info "blance history response is not a json object"
return
self.events.emit(SIGNAL_BALANCE_HISTORY_DATA_READY, TokenBalanceHistoryDataArgs(
result: response
))
proc getHistoricalDataForToken*(self: Service, symbol: string, currency: string, range: int) = proc getHistoricalDataForToken*(self: Service, symbol: string, currency: string, range: int) =
let arg = GetTokenHistoricalDataTaskArg( let arg = GetTokenHistoricalDataTaskArg(
tptr: cast[ByteAddress](getTokenHistoricalDataTask), tptr: cast[ByteAddress](getTokenHistoricalDataTask),
@ -143,6 +187,18 @@ QtObject:
) )
self.threadpool.start(arg) self.threadpool.start(arg)
# Historical Balance
proc tokenBalanceHistoryDataResolved*(self: Service, response: string) {.slot.} =
# TODO
let responseObj = response.parseJson
if (responseObj.kind != JObject):
info "blance history response is not a json object"
return
self.events.emit(SIGNAL_BALANCE_HISTORY_DATA_READY, TokenBalanceHistoryDataArgs(
result: response
))
proc fetchHistoricalBalanceForTokenAsJson*(self: Service, address: string, symbol: string, timeInterval: BalanceHistoryTimeInterval) = proc fetchHistoricalBalanceForTokenAsJson*(self: Service, address: string, symbol: string, timeInterval: BalanceHistoryTimeInterval) =
let networks = self.networkService.getNetworks() let networks = self.networkService.getNetworks()
for network in networks: for network in networks:

View File

@ -22,6 +22,49 @@ type BalanceDto* = object
address*: string address*: string
chainId*: int chainId*: int
type
TokenMarketValuesDto* = object
marketCap*: float64
highDay*: float64
lowDay*: float64
changePctHour*: float64
changePctDay*: float64
changePct24hour*: float64
change24hour*: float64
price*: float64
proc newTokenMarketValuesDto*(
marketCap: float64,
highDay: float64,
lowDay: float64,
changePctHour: float64,
changePctDay: float64,
changePct24hour: float64,
change24hour: float64,
price: float64
): TokenMarketValuesDto =
return TokenMarketValuesDto(
marketCap: marketCap,
highDay: highDay,
lowDay: lowDay,
changePctHour: changePctHour,
changePctDay: changePctDay,
changePct24hour: changePct24hour,
change24hour: change24hour,
price: price,
)
proc toTokenMarketValuesDto*(jsonObj: JsonNode): TokenMarketValuesDto =
result = TokenMarketValuesDto()
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)
discard jsonObj.getProp("price", result.price)
type type
WalletTokenDto* = object WalletTokenDto* = object
name*: string name*: string
@ -32,14 +75,8 @@ type
description*: string description*: string
assetWebsiteUrl*: string assetWebsiteUrl*: string
builtOn*: string builtOn*: string
marketCap*: string pegSymbol*: string
highDay*: string marketValuesPerCurrency*: Table[string, TokenMarketValuesDto]
lowDay*: string
changePctHour*: string
changePctDay*: string
changePct24hour*: string
change24hour*: string
currencyPrice*: float64
type type
WalletAccountDto* = ref object of RootObj WalletAccountDto* = ref object of RootObj
@ -123,11 +160,12 @@ proc getBalance*(self: WalletTokenDto, chainIds: seq[int]): float64 =
return sum return sum
proc getCurrencyBalance*(self: WalletTokenDto, chainIds: seq[int]): float64 = proc getCurrencyBalance*(self: WalletTokenDto, chainIds: seq[int], currency: string): float64 =
var sum = 0.0 var sum = 0.0
let price = if self.marketValuesPerCurrency.hasKey(currency): self.marketValuesPerCurrency[currency].price else: 0.0
for chainId in chainIds: for chainId in chainIds:
if self.balancesPerChain.hasKey(chainId): if self.balancesPerChain.hasKey(chainId):
sum += self.balancesPerChain[chainId].getCurrencyBalance(self.currencyPrice) sum += self.balancesPerChain[chainId].getCurrencyBalance(price)
return sum return sum
@ -148,8 +186,8 @@ proc getVisibleForNetworkWithPositiveBalance*(self: WalletTokenDto, chainIds: se
return false return false
proc getCurrencyBalance*(self: WalletAccountDto, chainIds: seq[int]): float64 = proc getCurrencyBalance*(self: WalletAccountDto, chainIds: seq[int], currency: string): float64 =
return self.tokens.map(t => t.getCurrencyBalance(chainIds)).foldl(a + b, 0.0) return self.tokens.map(t => t.getCurrencyBalance(chainIds, currency)).foldl(a + b, 0.0)
proc toBalanceDto*(jsonObj: JsonNode): BalanceDto = proc toBalanceDto*(jsonObj: JsonNode): BalanceDto =
result = BalanceDto() result = BalanceDto()
@ -166,14 +204,12 @@ proc toWalletTokenDto*(jsonObj: JsonNode): WalletTokenDto =
discard jsonObj.getProp("description", result.description) discard jsonObj.getProp("description", result.description)
discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl) discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl)
discard jsonObj.getProp("builtOn", result.builtOn) discard jsonObj.getProp("builtOn", result.builtOn)
discard jsonObj.getProp("marketCap", result.marketCap) discard jsonObj.getProp("pegSymbol", result.pegSymbol)
discard jsonObj.getProp("highDay", result.highDay)
discard jsonObj.getProp("lowDay", result.lowDay) var marketValuesPerCurrencyObj: JsonNode
discard jsonObj.getProp("changePctHour", result.changePctHour) if(jsonObj.getProp("marketValuesPerCurrency", marketValuesPerCurrencyObj)):
discard jsonObj.getProp("changePctDay", result.changePctDay) for currency, marketValuesObj in marketValuesPerCurrencyObj:
discard jsonObj.getProp("changePct24hour", result.changePct24hour) result.marketValuesPerCurrency[currency] = marketValuesObj.toTokenMarketValuesDto()
discard jsonObj.getProp("change24hour", result.change24hour)
discard jsonObj.getProp("currencyPrice", result.currencyPrice)
var balancesPerChainObj: JsonNode var balancesPerChainObj: JsonNode
if(jsonObj.getProp("balancesPerChain", balancesPerChainObj)): if(jsonObj.getProp("balancesPerChain", balancesPerChainObj)):

View File

@ -17,7 +17,6 @@ import ../../../backend/accounts as status_go_accounts
import ../../../backend/backend as backend import ../../../backend/backend as backend
import ../../../backend/eth as status_go_eth import ../../../backend/eth as status_go_eth
import ../../../backend/transactions as status_go_transactions import ../../../backend/transactions as status_go_transactions
import ../../../backend/cache
export dto, derived_address, key_pair_dto export dto, derived_address, key_pair_dto
@ -101,7 +100,6 @@ include ../../common/json_utils
QtObject: QtObject:
type Service* = ref object of QObject type Service* = ref object of QObject
closingApp: bool closingApp: bool
ignoreTimeInitiatedTokensBuild: bool
events: EventEmitter events: EventEmitter
threadpool: ThreadPool threadpool: ThreadPool
settingsService: settings_service.Service settingsService: settings_service.Service
@ -109,11 +107,7 @@ QtObject:
tokenService: token_service.Service tokenService: token_service.Service
networkService: network_service.Service networkService: network_service.Service
walletAccounts: OrderedTable[string, WalletAccountDto] walletAccounts: OrderedTable[string, WalletAccountDto]
timerStartTimeInSeconds: int64
priceCache: TimedCache
processedKeyPair: KeyPairDto processedKeyPair: KeyPairDto
ignoreTimeInitiatedHistoryFetchBuild: bool
isHistoryFetchTimerAlreadyRunning: bool
# Forward declaration # Forward declaration
proc buildAllTokens(self: Service, accounts: seq[string]) proc buildAllTokens(self: Service, accounts: seq[string])
@ -135,7 +129,6 @@ QtObject:
new(result, delete) new(result, delete)
result.QObject.setup result.QObject.setup
result.closingApp = false result.closingApp = false
result.ignoreTimeInitiatedTokensBuild = false
result.events = events result.events = events
result.threadpool = threadpool result.threadpool = threadpool
result.settingsService = settingsService result.settingsService = settingsService
@ -143,27 +136,6 @@ QtObject:
result.tokenService = tokenService result.tokenService = tokenService
result.networkService = networkService result.networkService = networkService
result.walletAccounts = initOrderedTable[string, WalletAccountDto]() result.walletAccounts = initOrderedTable[string, WalletAccountDto]()
result.priceCache = newTimedCache()
result.ignoreTimeInitiatedHistoryFetchBuild = false
result.isHistoryFetchTimerAlreadyRunning = false
proc getPrice*(self: Service, crypto: string, fiat: string): float64 =
let cacheKey = crypto & fiat
if self.priceCache.isCached(cacheKey):
return parseFloat(self.priceCache.get(cacheKey))
var prices = initTable[string, float]()
try:
let response = backend.fetchPrices(@[crypto], fiat)
for (symbol, value) in response.result.pairs:
prices[symbol] = value.getFloat
self.priceCache.set(cacheKey, $value.getFloat)
return prices[crypto]
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return 0.0
proc fetchAccounts*(self: Service): seq[WalletAccountDto] = proc fetchAccounts*(self: Service): seq[WalletAccountDto] =
let response = status_go_accounts.getAccounts() let response = status_go_accounts.getAccounts()
@ -360,6 +332,9 @@ QtObject:
self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountDeleted(account: accountDeleted)) self.events.emit(SIGNAL_WALLET_ACCOUNT_DELETED, AccountDeleted(account: accountDeleted))
proc getCurrency*(self: Service): string =
return self.settingsService.getCurrency()
proc updateCurrency*(self: Service, newCurrency: string) = proc updateCurrency*(self: Service, newCurrency: string) =
discard self.settingsService.saveCurrency(newCurrency) discard self.settingsService.saveCurrency(newCurrency)
self.buildAllTokens(self.getAddresses()) self.buildAllTokens(self.getAddresses())
@ -472,7 +447,7 @@ QtObject:
tokens.sort(priorityTokenCmp) tokens.sort(priorityTokenCmp)
self.walletAccounts[wAddress].tokens = tokens self.walletAccounts[wAddress].tokens = tokens
data.accountsTokens[wAddress] = tokens data.accountsTokens[wAddress] = tokens
self.tokenService.updateTokenPrices(tokens) # For efficiency. Will be removed when token info fetching gets moved to the tokenService
self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT, data) self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT, data)
except Exception as e: except Exception as e:
error "error: ", procName="onAllTokensBuilt", errName = e.name, errDesription = e.msg error "error: ", procName="onAllTokensBuilt", errName = e.name, errDesription = e.msg
@ -494,22 +469,28 @@ QtObject:
self.checkRecentHistory() self.checkRecentHistory()
self.startWallet() self.startWallet()
proc getNetworkCurrencyBalance*(self: Service, network: NetworkDto): float64 = proc getCurrentCurrencyIfEmpty(self: Service, currency: string): string =
if currency != "":
return currency
else:
return self.getCurrency()
proc getNetworkCurrencyBalance*(self: Service, network: NetworkDto, currency: string = ""): float64 =
for walletAccount in toSeq(self.walletAccounts.values): for walletAccount in toSeq(self.walletAccounts.values):
result += walletAccount.getCurrencyBalance(@[network.chainId]) result += walletAccount.getCurrencyBalance(@[network.chainId], self.getCurrentCurrencyIfEmpty(currency))
proc findTokenSymbolByAddress*(self: Service, address: string): string = proc findTokenSymbolByAddress*(self: Service, address: string): string =
return self.tokenService.findTokenSymbolByAddress(address) return self.tokenService.findTokenSymbolByAddress(address)
proc getCurrencyBalanceForAddress*(self: Service, address: string): float64 = proc getCurrencyBalanceForAddress*(self: Service, address: string, currency: string = ""): float64 =
let chainIds = self.networkService.getNetworks().map(n => n.chainId) let chainIds = self.networkService.getNetworks().map(n => n.chainId)
if not self.walletAccounts.hasKey(address): if not self.walletAccounts.hasKey(address):
return return
return self.walletAccounts[address].getCurrencyBalance(chainIds) return self.walletAccounts[address].getCurrencyBalance(chainIds, self.getCurrentCurrencyIfEmpty(currency))
proc getTotalCurrencyBalance*(self: Service): float64 = proc getTotalCurrencyBalance*(self: Service, currency: string = ""): float64 =
let chainIds = self.networkService.getNetworks().filter(a => a.enabled).map(a => a.chainId) 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) return self.getWalletAccounts().map(a => a.getCurrencyBalance(chainIds, self.getCurrentCurrencyIfEmpty(currency))).foldl(a + b, 0.0)
proc responseHasNoErrors(self: Service, procName: string, response: RpcResponse[JsonNode]): bool = proc responseHasNoErrors(self: Service, procName: string, response: RpcResponse[JsonNode]): bool =
var errMsg = "" var errMsg = ""

View File

@ -100,7 +100,7 @@ rpc(getTransactionEstimatedTime, "wallet"):
rpc(fetchPrices, "wallet"): rpc(fetchPrices, "wallet"):
symbols: seq[string] symbols: seq[string]
currency: string currencies: seq[string]
rpc(generateAccountWithDerivedPath, "accounts"): rpc(generateAccountWithDerivedPath, "accounts"):
password: string password: string
@ -219,7 +219,7 @@ rpc(deleteDappPermissionsByNameAndAddress, "permissions"):
rpc(fetchMarketValues, "wallet"): rpc(fetchMarketValues, "wallet"):
symbols: seq[string] symbols: seq[string]
currency: string currencies: seq[string]
rpc(fetchTokenDetails, "wallet"): rpc(fetchTokenDetails, "wallet"):
symbols: seq[string] symbols: seq[string]
@ -277,4 +277,10 @@ rpc(getName, "ens"):
rpc(getBalanceHistory, "wallet"): rpc(getBalanceHistory, "wallet"):
chainId: int chainId: int
address: string address: string
timeInterval: int timeInterval: int
rpc(isCurrencyFiat, "wallet"):
code: string
rpc(getFiatCurrencyMinorUnit, "wallet"):
code: string

View File

@ -23,7 +23,6 @@ SplitView {
SplitView.fillHeight: true SplitView.fillHeight: true
communitiesStore: CommunitiesStore { communitiesStore: CommunitiesStore {
readonly property string locale: ""
readonly property int unreadNotificationsCount: 42 readonly property int unreadNotificationsCount: 42
readonly property string communityTags: ModelsData.communityTags readonly property string communityTags: ModelsData.communityTags
readonly property var curatedCommunitiesModel: SortFilterProxyModel { readonly property var curatedCommunitiesModel: SortFilterProxyModel {

View File

@ -94,11 +94,11 @@ Rectangle {
*/ */
property ListModel categories: ListModel {} property ListModel categories: ListModel {}
/*! /*!
\qmlproperty string StatusCommunityCard::locale \qmlproperty var StatusCommunityCard::locale
This property holds the application locale used to give format to members number representation. This property holds the application locale used to give format to members number representation.
If not provided, default value is "en". If not provided, default value is "en".
*/ */
property string locale: "en" property var locale: Qt.locale("en")
/*! /*!
\qmlproperty url StatusCommunityCard::banner \qmlproperty url StatusCommunityCard::banner
This property holds the community banner image url. This property holds the community banner image url.
@ -148,14 +148,14 @@ Rectangle {
const ks = 1000 const ks = 1000
if(number > million) { if(number > million) {
res = number / million res = number / million
res = Number(number / million).toLocaleString(Qt.locale(root.locale), 'f', 1) + 'M' res = Number(number / million).toLocaleString(root.locale, 'f', 1) + 'M'
} }
else if(number > ks) { else if(number > ks) {
res = number / ks res = number / ks
res = Number(number / ks).toLocaleString(Qt.locale(root.locale), 'f', 1) + 'K' res = Number(number / ks).toLocaleString(root.locale, 'f', 1) + 'K'
} }
else else
res = Number(number).toLocaleString(Qt.locale(root.locale), 'f', 0) res = Number(number).toLocaleString(root.locale, 'f', 0)
return res return res
} }
} }

View File

@ -47,7 +47,7 @@ Item {
if (showBalanceForAssetSymbol == "" || minRequiredAssetBalance == 0 || !assetFound) { if (showBalanceForAssetSymbol == "" || minRequiredAssetBalance == 0 || !assetFound) {
return root.isValid return root.isValid
} }
root.isValid = assetFound.totalBalance >= minRequiredAssetBalance root.isValid = assetFound.totalBalance.amount >= minRequiredAssetBalance
return root.isValid return root.isValid
} }
@ -88,7 +88,7 @@ Item {
if (!assetFound) { if (!assetFound) {
return return
} }
txtAssetBalance.text = root.assetBalanceTextFn(assetFound.totalBalance) txtAssetBalance.text = root.assetBalanceTextFn(assetFound.totalBalance.amount)
txtAssetSymbol.text = " " + assetFound.symbol txtAssetSymbol.text = " " + assetFound.symbol
} }

View File

@ -33,10 +33,10 @@ StatusValidator {
property real bottom: qmlDoubleValidator.bottom property real bottom: qmlDoubleValidator.bottom
/*! /*!
\qmlproperty string StatusFloatValidator::locale \qmlproperty var StatusFloatValidator::locale
This property holds the name of the locale used to interpret the number. This property holds the locale used to interpret the number.
*/ */
property string locale property var locale: Qt.locale()
/*! /*!
\qmlproperty real StatusFloatValidator::top \qmlproperty real StatusFloatValidator::top

View File

@ -35,10 +35,10 @@ StatusValidator {
property int bottom property int bottom
/*! /*!
\qmlproperty string StatusIntValidator::locale \qmlproperty var StatusIntValidator::locale
This property holds the name of the locale used to interpret the number. This property holds the locale used to interpret the number.
*/ */
property string locale property var locale: Qt.locale()
/*! /*!
\qmlproperty string StatusIntValidator::top \qmlproperty string StatusIntValidator::top
@ -48,7 +48,7 @@ StatusValidator {
name: "intValidator" name: "intValidator"
errorMessage: qsTr("Please enter a valid numeric value.") errorMessage: qsTr("Please enter a valid numeric value.")
validatorObj: IntValidator { bottom: root.bottom; locale: root.locale; top: root.top } validatorObj: IntValidator { bottom: root.bottom; locale: root.locale.name; top: root.top }
validate: function (t) { validate: function (t) {
// Basic validation management // Basic validation management

View File

@ -17,6 +17,7 @@ ColumnLayout {
property alias amountText: amountInput.text property alias amountText: amountInput.text
property alias amount: amountInput.amount property alias amount: amountInput.amount
readonly property bool amountValid: amountInput.valid && amountInput.text.length > 0 readonly property bool amountValid: amountInput.valid && amountInput.text.length > 0
property var locale
signal pickerClicked signal pickerClicked
@ -66,5 +67,7 @@ ColumnLayout {
Layout.topMargin: 8 Layout.topMargin: 8
allowDecimals: false allowDecimals: false
locale: root.locale
} }
} }

View File

@ -291,6 +291,7 @@ StatusDropdown {
tokenName: d.defaultTokenNameText tokenName: d.defaultTokenNameText
amountText: d.tokenAmountText amountText: d.tokenAmountText
onAmountTextChanged: d.tokenAmountText = amountText onAmountTextChanged: d.tokenAmountText = amountText
locale: root.store.locale
readonly property real effectiveAmount: amountValid ? amount : 0 readonly property real effectiveAmount: amountValid ? amount : 0
onEffectiveAmountChanged: root.tokenAmount = effectiveAmount onEffectiveAmountChanged: root.tokenAmount = effectiveAmount
@ -343,6 +344,7 @@ StatusDropdown {
collectibleName: d.defaultCollectibleNameText collectibleName: d.defaultCollectibleNameText
amountText: d.collectibleAmountText amountText: d.collectibleAmountText
onAmountTextChanged: d.collectibleAmountText = amountText onAmountTextChanged: d.collectibleAmountText = amountText
locale: root.store.locale
readonly property real effectiveAmount: amountValid ? amount : 0 readonly property real effectiveAmount: amountValid ? amount : 0
onEffectiveAmountChanged: root.collectibleAmount = effectiveAmount onEffectiveAmountChanged: root.collectibleAmount = effectiveAmount

View File

@ -15,6 +15,7 @@ ColumnLayout {
property alias amountText: amountInput.text property alias amountText: amountInput.text
property alias amount: amountInput.amount property alias amount: amountInput.amount
readonly property bool amountValid: amountInput.valid && amountInput.text.length > 0 readonly property bool amountValid: amountInput.valid && amountInput.text.length > 0
property var locale
signal pickerClicked signal pickerClicked
@ -43,5 +44,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 8 Layout.topMargin: 8
locale: root.locale
} }
} }

View File

@ -7,7 +7,7 @@ import shared.stores 1.0
QtObject { QtObject {
id: root id: root
property string locale: localAppSettings.language property var locale: Qt.locale(localAppSettings.language)
property var contactsStore property var contactsStore
@ -464,7 +464,7 @@ QtObject {
property var accounts: walletSectionAccounts.model property var accounts: walletSectionAccounts.model
property var currentAccount: walletSectionCurrent property var currentAccount: walletSectionCurrent
property string currentCurrency: walletSection.currentCurrency property string currentCurrency: walletSection.currentCurrency
property CurrenciesStore currencyStore: CurrenciesStore { } property CurrenciesStore currencyStore: CurrenciesStore {}
property var allNetworks: networksModule.all property var allNetworks: networksModule.all
property var savedAddressesModel: walletSectionSavedAddresses.model property var savedAddressesModel: walletSectionSavedAddresses.model

View File

@ -28,7 +28,7 @@ QtObject {
property bool discordImportHasCommunityImage: root.communitiesModuleInst.discordImportHasCommunityImage property bool discordImportHasCommunityImage: root.communitiesModuleInst.discordImportHasCommunityImage
property var discordImportTasks: root.communitiesModuleInst.discordImportTasks property var discordImportTasks: root.communitiesModuleInst.discordImportTasks
property bool downloadingCommunityHistoryArchives: root.communitiesModuleInst.downloadingCommunityHistoryArchives property bool downloadingCommunityHistoryArchives: root.communitiesModuleInst.downloadingCommunityHistoryArchives
property string locale: localAppSettings.language property var locale: Qt.locale(localAppSettings.language)
property var advancedModule: profileSectionModule.advancedModule property var advancedModule: profileSectionModule.advancedModule
// TODO: Could the backend provide directly 2 filtered models?? // TODO: Could the backend provide directly 2 filtered models??

View File

@ -18,7 +18,7 @@ import "../stores"
Item { Item {
id: root id: root
property string locale: "" property var locale
property string currency: "" property string currency: ""
property var currentAccount property var currentAccount
property var store property var store
@ -46,7 +46,7 @@ Item {
font.pixelSize: 28 font.pixelSize: 28
font.bold: true font.bold: true
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
text: "%1 %2".arg(Utils.toLocaleString(root.currentAccount.currencyBalance.toFixed(2), root.locale, {"currency": true})).arg(root.currency.toUpperCase()) text: LocaleUtils.currencyAmountToLocaleString(root.currentAccount.currencyBalance, root.locale)
} }
} }

View File

@ -59,6 +59,7 @@ StatusModal {
root.selectedAccount = newAccount root.selectedAccount = newAccount
} }
showAllWalletTypes: true showAllWalletTypes: true
locale: RootStore.locale
} }
contentItem: Column { contentItem: Column {

View File

@ -22,12 +22,12 @@ QtObject {
property var generatedAccounts: walletSectionAccounts.generated property var generatedAccounts: walletSectionAccounts.generated
property var appSettings: localAppSettings property var appSettings: localAppSettings
property var accountSensitiveSettings: localAccountSensitiveSettings property var accountSensitiveSettings: localAccountSensitiveSettings
property string locale: Qt.locale().name property var locale: Qt.locale(appSettings.language)
property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal
property var currencyStore: SharedStore.RootStore.currencyStore property var currencyStore: SharedStore.RootStore.currencyStore
property string currentCurrency: currencyStore.currentCurrency property string currentCurrency: currencyStore.currentCurrency
property string totalCurrencyBalance: walletSection.totalCurrencyBalance property var totalCurrencyBalance: walletSection.totalCurrencyBalance
property string signingPhrase: walletSection.signingPhrase property string signingPhrase: walletSection.signingPhrase
property string mnemonicBackedUp: walletSection.isMnemonicBackedUp property string mnemonicBackedUp: walletSection.isMnemonicBackedUp

View File

@ -82,7 +82,7 @@ Rectangle {
objectName: "walletLeftListAmountValue" objectName: "walletLeftListAmountValue"
color: Style.current.textColor color: Style.current.textColor
text: { text: {
Utils.toLocaleString(parseFloat(RootStore.totalCurrencyBalance).toFixed(2), localAppSettings.language, {"currency": true}) + " " + RootStore.currentCurrency.toUpperCase() LocaleUtils.currencyAmountToLocaleString(RootStore.totalCurrencyBalance, RootStore.currencyStore.locale)
} }
selectByMouse: true selectByMouse: true
cursorVisible: true cursorVisible: true
@ -117,7 +117,7 @@ Rectangle {
width: ListView.view.width width: ListView.view.width
highlighted: RootStore.currentAccount.name === model.name highlighted: RootStore.currentAccount.name === model.name
title: model.name title: model.name
subTitle: Utils.toLocaleString(model.currencyBalance.toFixed(2), RootStore.locale, {"model.currency": true}) + " " + RootStore.currentCurrency.toUpperCase() subTitle: LocaleUtils.currencyAmountToLocaleString(model.currencyBalance, RootStore.currencyStore.locale)
asset.emoji: !!model.emoji ? model.emoji: "" asset.emoji: !!model.emoji ? model.emoji: ""
asset.color: model.color asset.color: model.color
asset.name: !model.emoji ? "filled-account": "" asset.name: !model.emoji ? "filled-account": ""

View File

@ -92,6 +92,7 @@ Item {
AssetsView { AssetsView {
account: RootStore.currentAccount account: RootStore.currentAccount
assetDetailsLaunched: stack.currentIndex === 2 assetDetailsLaunched: stack.currentIndex === 2
locale: RootStore.locale
onAssetClicked: { onAssetClicked: {
assetDetailView.token = token assetDetailView.token = token
stack.currentIndex = 2 stack.currentIndex = 2

View File

@ -7,7 +7,7 @@ import "../Profile/stores"
QtObject { QtObject {
id: root id: root
property string locale: localAppSettings.language property var locale: Qt.locale(localAppSettings.language)
property var mainModuleInst: mainModule property var mainModuleInst: mainModule
property var aboutModuleInst: aboutModule property var aboutModuleInst: aboutModule

View File

@ -10,7 +10,7 @@ Input {
id: root id: root
property int maximumLength: 10 property int maximumLength: 10
property var locale: Qt.locale() property var locale
readonly property alias amount: d.amount readonly property alias amount: d.amount
readonly property bool valid: validationError.length === 0 readonly property bool valid: validationError.length === 0
@ -40,7 +40,7 @@ Input {
decimals: root.allowDecimals ? 100 : 0 decimals: root.allowDecimals ? 100 : 0
bottom: 0 bottom: 0
notation: DoubleValidator.StandardNotation notation: DoubleValidator.StandardNotation
locale: root.locale.name locale: root.locale
} }
onTextChanged: { onTextChanged: {

View File

@ -181,7 +181,7 @@ Item {
if (!selectAsset.selectedAsset) { if (!selectAsset.selectedAsset) {
return return
} }
txtBalance.text = Utils.stripTrailingZeros(parseFloat(selectAsset.selectedAsset.balance).toFixed(4)) txtBalance.text = Utils.stripTrailingZeros(selectAsset.selectedAsset.balance.amount.toFixed(4))
if (inputAmount.text === "" || isNaN(inputAmount.text)) { if (inputAmount.text === "" || isNaN(inputAmount.text)) {
return return
} }

View File

@ -10,7 +10,7 @@ Item {
id: assetDelegate id: assetDelegate
objectName: symbol objectName: symbol
property string locale: "" property var locale
property string currency: "" property string currency: ""
property string currencySymbol: "" property string currencySymbol: ""
@ -52,7 +52,7 @@ Item {
anchors.leftMargin: Style.current.smallPadding anchors.leftMargin: Style.current.smallPadding
font.pixelSize: 15 font.pixelSize: 15
color: Style.current.secondaryText color: Style.current.secondaryText
text: qsTr("%1 %2").arg(enabledNetworkBalance.toString()).arg(symbol) text: LocaleUtils.currencyAmountToLocaleString(enabledNetworkBalance, root.locale)
} }
StyledText { StyledText {
@ -63,6 +63,6 @@ Item {
anchors.rightMargin: 0 anchors.rightMargin: 0
font.pixelSize: 15 font.pixelSize: 15
font.strikeout: false font.strikeout: false
text: enabledNetworkCurrencyBalance.toLocaleCurrencyString(Qt.locale(), assetDelegate.currencySymbol) text: LocaleUtils.currencyAmountToLocaleString(enabledNetworkCurrencyBalance, root.locale)
} }
} }

View File

@ -22,6 +22,7 @@ Control {
} }
property var getNetworkColor: function(chainId){} property var getNetworkColor: function(chainId){}
property var getNetworkIcon: function(chainId){} property var getNetworkIcon: function(chainId){}
property var formatBalance: function(balance){}
topPadding: Style.current.padding topPadding: Style.current.padding
@ -77,7 +78,7 @@ Control {
id: chainRepeater id: chainRepeater
model: balances ? balances : null model: balances ? balances : null
delegate: InformationTag { delegate: InformationTag {
tagPrimaryLabel.text: model.balance tagPrimaryLabel.text: root.formatBalance(model.balance)
tagPrimaryLabel.color: root.getNetworkColor(model.chainId) tagPrimaryLabel.color: root.getNetworkColor(model.chainId)
image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(model.chainId))) image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(model.chainId)))
} }

View File

@ -8,14 +8,14 @@ import utils 1.0
StatusListItem { StatusListItem {
id: root id: root
property string currentCurrencySymbol property var locale
property var getNetworkIcon: function(chainId){ property var getNetworkIcon: function(chainId){
return "" return ""
} }
signal tokenSelected(var selectedToken) signal tokenSelected(var selectedToken)
title: name title: name
label: enabledNetworkCurrencyBalance.toLocaleCurrencyString(Qt.locale(), root.currentCurrencySymbol) label: LocaleUtils.currencyAmountToLocaleString(enabledNetworkCurrencyBalance, root.locale)
asset.name: symbol ? Style.png("tokens/" + symbol) : "" asset.name: symbol ? Style.png("tokens/" + symbol) : ""
asset.isImage: true asset.isImage: true
asset.width: 32 asset.width: 32
@ -34,14 +34,14 @@ StatusListItem {
width: 16 width: 16
height: 16 height: 16
image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(chainId))) image.source: Style.svg("tiny/%1".arg(root.getNetworkIcon(chainId)))
visible: balance > 0 visible: balance.amount > 0
} }
} }
Component { Component {
id: expandedItem id: expandedItem
StatusListItemTag { StatusListItemTag {
height: 16 height: 16
title: balance title: LocaleUtils.currencyAmountToLocaleString(balance, root.locale)
titleText.font.pixelSize: 12 titleText.font.pixelSize: 12
closeButtonVisible: false closeButtonVisible: false
bgColor: "transparent" bgColor: "transparent"
@ -49,7 +49,7 @@ StatusListItem {
asset.height: 16 asset.height: 16
asset.isImage: true asset.isImage: true
asset.name: Style.svg("tiny/%1".arg(root.getNetworkIcon(chainId))) asset.name: Style.svg("tiny/%1".arg(root.getNetworkIcon(chainId)))
visible: balance > 0 visible: balance.amount > 0
} }
} }
} }

View File

@ -9,10 +9,10 @@ import StatusQ.Core 0.1
import utils 1.0 import utils 1.0
StatusListItem { StatusListItem {
property string currentCurrencySymbol id: root
property var locale
title: name title: name
subTitle: `${enabledNetworkBalance} ${symbol}` subTitle: LocaleUtils.currencyAmountToLocaleString(enabledNetworkBalance, root.locale)
asset.name: symbol ? Style.png("tokens/" + symbol) : "" asset.name: symbol ? Style.png("tokens/" + symbol) : ""
asset.isImage: true asset.isImage: true
components: [ components: [
@ -25,7 +25,7 @@ StatusListItem {
anchors.right: parent.right anchors.right: parent.right
font.pixelSize: 15 font.pixelSize: 15
font.strikeout: false font.strikeout: false
text: enabledNetworkCurrencyBalance.toLocaleCurrencyString(Qt.locale(), currentCurrencySymbol) text: LocaleUtils.currencyAmountToLocaleString(enabledNetworkCurrencyBalance, root.locale)
} }
Row { Row {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@ -35,7 +35,7 @@ StatusListItem {
font.pixelSize: 15 font.pixelSize: 15
font.strikeout: false font.strikeout: false
color: valueColumn.textColor color: valueColumn.textColor
text: currencyPrice.toLocaleCurrencyString(Qt.locale(), currentCurrencySymbol) text: LocaleUtils.currencyAmountToLocaleString(currencyPrice, root.locale)
} }
Rectangle { Rectangle {
width: 1 width: 1
@ -46,7 +46,7 @@ StatusListItem {
font.pixelSize: 15 font.pixelSize: 15
font.strikeout: false font.strikeout: false
color: valueColumn.textColor color: valueColumn.textColor
text: changePct24hour !== "" ? "%1%".arg(changePct24hour) : "---" text: changePct24hour !== "" ? changePct24hour.toFixed(2) + "%" : "---"
} }
} }
} }

View File

@ -27,6 +27,7 @@ Item {
property string userSelectedToken property string userSelectedToken
property string currentCurrencySymbol property string currentCurrencySymbol
property string placeholderText property string placeholderText
property var locale
property var tokenAssetSourceFn: function (symbol) { property var tokenAssetSourceFn: function (symbol) {
return "" return ""
@ -149,7 +150,7 @@ Item {
delegate: TokenBalancePerChainDelegate { delegate: TokenBalancePerChainDelegate {
objectName: "AssetSelector_ItemDelegate_" + symbol objectName: "AssetSelector_ItemDelegate_" + symbol
width: comboBox.control.popup.width width: comboBox.control.popup.width
currentCurrencySymbol: root.currentCurrencySymbol locale: root.locale
getNetworkIcon: root.getNetworkIcon getNetworkIcon: root.getNetworkIcon
onTokenSelected: { onTokenSelected: {
userSelectedToken = selectedToken.symbol userSelectedToken = selectedToken.symbol

View File

@ -18,6 +18,7 @@ import "../views"
StatusFloatingButtonsSelector { StatusFloatingButtonsSelector {
id: root id: root
property var locale
property var selectedAccount property var selectedAccount
// Expected signature: function(newAccount, newIndex) // Expected signature: function(newAccount, newIndex)
property var changeSelectedAccount: function(){} property var changeSelectedAccount: function(){}
@ -88,7 +89,7 @@ StatusFloatingButtonsSelector {
popupMenuDelegate: StatusListItem { popupMenuDelegate: StatusListItem {
implicitWidth: 272 implicitWidth: 272
title: name title: name
subTitle: currencyBalance subTitle: LocaleUtils.currencyAmountToLocaleString(currencyBalance, locale)
asset.emoji: !!emoji ? emoji: "" asset.emoji: !!emoji ? emoji: ""
asset.color: model.color asset.color: model.color
asset.name: !emoji ? "filled-account": "" asset.name: !emoji ? "filled-account": ""

View File

@ -81,9 +81,9 @@ StatusDialog {
readonly property int errorType: !amountToSendInput.input.valid ? Constants.SendAmountExceedsBalance : readonly property int errorType: !amountToSendInput.input.valid ? Constants.SendAmountExceedsBalance :
(networkSelector.bestRoutes && networkSelector.bestRoutes.length <= 0 && !!amountToSendInput.input.text && recipientReady && !popup.isLoading) ? (networkSelector.bestRoutes && networkSelector.bestRoutes.length <= 0 && !!amountToSendInput.input.text && recipientReady && !popup.isLoading) ?
Constants.NoRoute : Constants.NoError Constants.NoRoute : Constants.NoError
readonly property double maxFiatBalance: !!assetSelector.selectedAsset ? (amountToSendInput.cryptoFiatFlipped ? readonly property var maxFiatBalance: !!assetSelector.selectedAsset ? (amountToSendInput.cryptoFiatFlipped ?
assetSelector.selectedAsset.totalCurrencyBalance : assetSelector.selectedAsset.totalCurrencyBalance :
assetSelector.selectedAsset.totalBalance): 0 assetSelector.selectedAsset.totalBalance): undefined
readonly property bool errorMode: popup.isLoading || !recipientReady ? false : errorType !== Constants.NoError || networkSelector.errorMode || isNaN(amountToSendInput.input.text) readonly property bool errorMode: popup.isLoading || !recipientReady ? false : errorType !== Constants.NoError || networkSelector.errorMode || isNaN(amountToSendInput.input.text)
readonly property bool recipientReady: (isAddressValid || isENSValid) && !recipientSelector.isPending readonly property bool recipientReady: (isAddressValid || isENSValid) && !recipientSelector.isPending
property bool isAddressValid: Utils.isValidAddress(popup.addressText) property bool isAddressValid: Utils.isValidAddress(popup.addressText)
@ -239,11 +239,12 @@ StatusDialog {
} }
popup.recalculateRoutesAndFees() popup.recalculateRoutesAndFees()
} }
locale: popup.store.locale
} }
StatusListItemTag { StatusListItemTag {
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
Layout.preferredHeight: 22 Layout.preferredHeight: 22
title: d.maxFiatBalance > 0 ? qsTr("Max: %1").arg(LocaleUtils.numberToLocaleString(d.maxFiatBalance)) : qsTr("No balances active") title: d.maxFiatBalance && d.maxFiatBalance.amount > 0 ? qsTr("Max: %1").arg(LocaleUtils.currencyAmountToLocaleString(d.maxFiatBalance, popup.store.locale)) : qsTr("No balances active")
closeButtonVisible: false closeButtonVisible: false
titleText.font.pixelSize: 12 titleText.font.pixelSize: 12
bgColor: amountToSendInput.input.valid ? Theme.palette.primaryColor3 : Theme.palette.dangerColor2 bgColor: amountToSendInput.input.valid ? Theme.palette.primaryColor3 : Theme.palette.dangerColor2
@ -255,6 +256,7 @@ StatusDialog {
AmountToSend { AmountToSend {
id: amountToSendInput id: amountToSendInput
Layout.fillWidth:true Layout.fillWidth:true
locale: popup.store.locale
isBridgeTx: popup.isBridgeTx isBridgeTx: popup.isBridgeTx
interactive: popup.interactive interactive: popup.interactive
selectedAsset: assetSelector.selectedAsset selectedAsset: assetSelector.selectedAsset
@ -272,6 +274,7 @@ StatusDialog {
id: amountToReceive id: amountToReceive
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.fillWidth:true Layout.fillWidth:true
locale: popup.store.locale
visible: popup.bestRoutes !== undefined && popup.bestRoutes.length > 0 visible: popup.bestRoutes !== undefined && popup.bestRoutes.length > 0
store: popup.store store: popup.store
isLoading: popup.isLoading isLoading: popup.isLoading
@ -287,7 +290,7 @@ StatusDialog {
anchors.right: parent.right anchors.right: parent.right
visible: !assetSelector.selectedAsset visible: !assetSelector.selectedAsset
assets: popup.selectedAccount && popup.selectedAccount.assets ? popup.selectedAccount.assets : [] assets: popup.selectedAccount && popup.selectedAccount.assets ? popup.selectedAccount.assets : []
currentCurrencySymbol: RootStore.currencyStore.currentCurrencySymbol locale: popup.store.locale
searchTokenSymbolByAddressFn: function (address) { searchTokenSymbolByAddressFn: function (address) {
if(popup.selectedAccount) { if(popup.selectedAccount) {
return popup.selectedAccount.findTokenSymbolByAddress(address) return popup.selectedAccount.findTokenSymbolByAddress(address)
@ -400,6 +403,7 @@ StatusDialog {
d.waitTimer.restart() d.waitTimer.restart()
} }
visible: !d.recipientReady && !isBridgeTx && !!assetSelector.selectedAsset visible: !d.recipientReady && !isBridgeTx && !!assetSelector.selectedAsset
locale: popup.store.locale
} }
NetworkSelector { NetworkSelector {
@ -445,7 +449,7 @@ StatusDialog {
footer: SendModalFooter { footer: SendModalFooter {
nextButtonText: popup.isBridgeTx ? qsTr("Bridge") : qsTr("Send") nextButtonText: popup.isBridgeTx ? qsTr("Bridge") : qsTr("Send")
maxFiatFees: popup.isLoading ? "..." : "%1 %2".arg(LocaleUtils.numberToLocaleString(d.totalFeesInFiat)).arg(popup.store.currentCurrency.toUpperCase()) maxFiatFees: popup.isLoading ? "..." : "%1 %2".arg(LocaleUtils.numberToLocaleString(d.totalFeesInFiat, -1, popup.store.locale)).arg(popup.store.currentCurrency.toUpperCase())
totalTimeEstimate: popup.isLoading? "..." : d.totalTimeEstimate totalTimeEstimate: popup.isLoading? "..." : d.totalTimeEstimate
pending: d.isPendingTx || popup.isLoading pending: d.isPendingTx || popup.isLoading
visible: d.recipientReady && !isNaN(amountToSendInput.cryptoValueToSend) && !d.errorMode visible: d.recipientReady && !isNaN(amountToSendInput.cryptoValueToSend) && !d.errorMode

View File

@ -131,10 +131,10 @@ Rectangle {
text: { text: {
if (Global.appMain) { if (Global.appMain) {
return "%1%2".arg(SharedStore.RootStore.currencyStore.currentCurrencySymbol) return "%1%2".arg(SharedStore.RootStore.currencyStore.currentCurrencySymbol)
.arg(Utils.toLocaleString(model.account.balance.toFixed(2), appSettings.locale, {"model.account.currency": true})) .arg(Utils.toLocaleString(parseFloat(model.account.balance.amount).toFixed(2), appSettings.locale, {"model.account.currency": true}))
} }
// without language/model refactor no way to read currency symbol or `appSettings.locale` before user logs in // without language/model refactor no way to read currency symbol or `appSettings.locale` before user logs in
return "$%1".arg(Utils.toLocaleString(model.account.balance.toFixed(2), localAppSettings.language, {"model.account.currency": true})) return "$%1".arg(Utils.toLocaleString(parseFloat(model.account.balance.amount).toFixed(2), localAppSettings.language, {"model.account.currency": true}))
} }
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.pixelSize: Constants.keycard.general.fontSize2 font.pixelSize: Constants.keycard.general.fontSize2

View File

@ -4,15 +4,20 @@ import utils 1.0
QtObject { QtObject {
id: root id: root
property var locale: Qt.locale(localAppSettings.language)
property string currentCurrency: walletSection.currentCurrency property string currentCurrency: walletSection.currentCurrency
property string currentCurrencySymbol: { property int currentCurrencyModelIndex: {
for (var i=0; i<currenciesModel.count; i++) { for (var i=0; i<currenciesModel.count; i++) {
if (currenciesModel.get(i).key === currentCurrency) { if (currenciesModel.get(i).key === currentCurrency) {
return currenciesModel.get(i).symbol; return i;
} }
} }
return ""; return 0;
} }
property string currentCurrencySymbol: currenciesModel.get(currentCurrencyModelIndex).symbol
property ListModel currenciesModel: ListModel { property ListModel currenciesModel: ListModel {
ListElement { ListElement {
key: "usd" key: "usd"
@ -22,6 +27,7 @@ QtObject {
category: "" category: ""
imageSource: "../../assets/twemoji/svg/1f1fa-1f1f8.svg" imageSource: "../../assets/twemoji/svg/1f1fa-1f1f8.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -32,6 +38,7 @@ QtObject {
category: "" category: ""
imageSource: "../../assets/twemoji/svg/1f1ec-1f1e7.svg" imageSource: "../../assets/twemoji/svg/1f1ec-1f1e7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -42,6 +49,7 @@ QtObject {
category: "" category: ""
imageSource: "../../assets/twemoji/svg/1f1ea-1f1fa.svg" imageSource: "../../assets/twemoji/svg/1f1ea-1f1fa.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -52,6 +60,7 @@ QtObject {
category: "" category: ""
imageSource: "../../assets/twemoji/svg/1f1f7-1f1fa.svg" imageSource: "../../assets/twemoji/svg/1f1f7-1f1fa.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -62,6 +71,7 @@ QtObject {
category: "" category: ""
imageSource: "../../assets/twemoji/svg/1f1f0-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1f0-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -72,6 +82,7 @@ QtObject {
category: qsTr("Tokens") category: qsTr("Tokens")
imageSource: "../../../../imports/assets/png/tokens/ETH.png" imageSource: "../../../../imports/assets/png/tokens/ETH.png"
selected: false selected: false
isToken: true
} }
ListElement { ListElement {
@ -82,6 +93,7 @@ QtObject {
category: qsTr("Tokens") category: qsTr("Tokens")
imageSource: "../../../../imports/assets/png/tokens/WBTC.png" imageSource: "../../../../imports/assets/png/tokens/WBTC.png"
selected: false selected: false
isToken: true
} }
ListElement { ListElement {
@ -92,6 +104,7 @@ QtObject {
category: qsTr("Tokens") category: qsTr("Tokens")
imageSource: "../../../../imports/assets/png/tokens/SNT.png" imageSource: "../../../../imports/assets/png/tokens/SNT.png"
selected: false selected: false
isToken: true
} }
ListElement { ListElement {
@ -102,6 +115,7 @@ QtObject {
category: qsTr("Tokens") category: qsTr("Tokens")
imageSource: "../../../../imports/assets/png/tokens/DAI.png" imageSource: "../../../../imports/assets/png/tokens/DAI.png"
selected: false selected: false
isToken: true
} }
ListElement { ListElement {
@ -112,6 +126,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e6-1f1ea.svg" imageSource: "../../assets/twemoji/svg/1f1e6-1f1ea.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -122,6 +137,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e6-1f1eb.svg" imageSource: "../../assets/twemoji/svg/1f1e6-1f1eb.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -132,6 +148,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e6-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1e6-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -142,6 +159,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e6-1f1fa.svg" imageSource: "../../assets/twemoji/svg/1f1e6-1f1fa.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -152,6 +170,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1e7.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1e7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -162,6 +181,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1e9.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1e9.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -172,6 +192,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1ec.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1ec.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -182,6 +203,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1ed.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1ed.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -192,6 +214,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1f3.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1f3.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -202,6 +225,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1f4.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1f4.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -212,6 +236,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -222,6 +247,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e7-1f1f9.svg" imageSource: "../../assets/twemoji/svg/1f1e7-1f1f9.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -232,6 +258,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e8-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1e8-1f1e6.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -242,6 +269,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e8-1f1ed.svg" imageSource: "../../assets/twemoji/svg/1f1e8-1f1ed.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -252,6 +280,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e8-1f1f1.svg" imageSource: "../../assets/twemoji/svg/1f1e8-1f1f1.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -262,6 +291,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e8-1f1f3.svg" imageSource: "../../assets/twemoji/svg/1f1e8-1f1f3.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -282,6 +312,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e8-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1e8-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -292,6 +323,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e8-1f1ff.svg" imageSource: "../../assets/twemoji/svg/1f1e8-1f1ff.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -302,6 +334,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e9-1f1f0.svg" imageSource: "../../assets/twemoji/svg/1f1e9-1f1f0.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -312,6 +345,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1e9-1f1f4.svg" imageSource: "../../assets/twemoji/svg/1f1e9-1f1f4.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -322,6 +356,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ea-1f1ec.svg" imageSource: "../../assets/twemoji/svg/1f1ea-1f1ec.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -332,6 +367,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ea-1f1f9.svg" imageSource: "../../assets/twemoji/svg/1f1ea-1f1f9.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -342,6 +378,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ec-1f1ea.svg" imageSource: "../../assets/twemoji/svg/1f1ec-1f1ea.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -352,6 +389,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ec-1f1ed.svg" imageSource: "../../assets/twemoji/svg/1f1ec-1f1ed.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -362,6 +400,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ed-1f1f0.svg" imageSource: "../../assets/twemoji/svg/1f1ed-1f1f0.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -372,6 +411,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ed-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1ed-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -382,6 +422,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ed-1f1fa.svg" imageSource: "../../assets/twemoji/svg/1f1ed-1f1fa.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -392,6 +433,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ee-1f1e9.svg" imageSource: "../../assets/twemoji/svg/1f1ee-1f1e9.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -402,6 +444,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ee-1f1f1.svg" imageSource: "../../assets/twemoji/svg/1f1ee-1f1f1.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -412,6 +455,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ee-1f1f3.svg" imageSource: "../../assets/twemoji/svg/1f1ee-1f1f3.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -422,6 +466,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ee-1f1f8.svg" imageSource: "../../assets/twemoji/svg/1f1ee-1f1f8.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -432,6 +477,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ef-1f1f2.svg" imageSource: "../../assets/twemoji/svg/1f1ef-1f1f2.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -442,6 +488,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ef-1f1f5.svg" imageSource: "../../assets/twemoji/svg/1f1ef-1f1f5.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -452,6 +499,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f0-1f1ea.svg" imageSource: "../../assets/twemoji/svg/1f1f0-1f1ea.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -462,6 +510,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f0-1f1fc.svg" imageSource: "../../assets/twemoji/svg/1f1f0-1f1fc.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -472,6 +521,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f0-1f1ff.svg" imageSource: "../../assets/twemoji/svg/1f1f0-1f1ff.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -482,6 +532,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f1-1f1f0.svg" imageSource: "../../assets/twemoji/svg/1f1f1-1f1f0.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -492,6 +543,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1e6.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -502,6 +554,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1e9.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1e9.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -512,6 +565,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -522,6 +576,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1fc.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1fc.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -532,6 +587,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1fd.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1fd.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -542,6 +598,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1fe.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1fe.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -552,6 +609,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f2-1f1ff.svg" imageSource: "../../assets/twemoji/svg/1f1f2-1f1ff.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -562,6 +620,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f3-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1f3-1f1e6.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -572,6 +631,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f3-1f1ec.svg" imageSource: "../../assets/twemoji/svg/1f1f3-1f1ec.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -582,6 +642,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f3-1f1f4.svg" imageSource: "../../assets/twemoji/svg/1f1f3-1f1f4.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -592,6 +653,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f3-1f1f5.svg" imageSource: "../../assets/twemoji/svg/1f1f3-1f1f5.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -602,6 +664,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f3-1f1ff.svg" imageSource: "../../assets/twemoji/svg/1f1f3-1f1ff.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -622,6 +685,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f5-1f1ea.svg" imageSource: "../../assets/twemoji/svg/1f1f5-1f1ea.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -632,6 +696,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f5-1f1ec.svg" imageSource: "../../assets/twemoji/svg/1f1f5-1f1ec.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -642,6 +707,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f5-1f1ed.svg" imageSource: "../../assets/twemoji/svg/1f1f5-1f1ed.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -652,6 +718,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f5-1f1f0.svg" imageSource: "../../assets/twemoji/svg/1f1f5-1f1f0.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -662,6 +729,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f5-1f1f1.svg" imageSource: "../../assets/twemoji/svg/1f1f5-1f1f1.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -672,6 +740,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f5-1f1fe.svg" imageSource: "../../assets/twemoji/svg/1f1f5-1f1fe.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -682,6 +751,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f6-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1f6-1f1e6.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -692,6 +762,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f7-1f1f4.svg" imageSource: "../../assets/twemoji/svg/1f1f7-1f1f4.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -702,6 +773,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f7-1f1f8.svg" imageSource: "../../assets/twemoji/svg/1f1f7-1f1f8.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -712,6 +784,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f8-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1f8-1f1e6.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -722,6 +795,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f8-1f1ea.svg" imageSource: "../../assets/twemoji/svg/1f1f8-1f1ea.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -732,6 +806,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f8-1f1ec.svg" imageSource: "../../assets/twemoji/svg/1f1f8-1f1ec.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -742,6 +817,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f9-1f1ed.svg" imageSource: "../../assets/twemoji/svg/1f1f9-1f1ed.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -752,6 +828,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f9-1f1f9.svg" imageSource: "../../assets/twemoji/svg/1f1f9-1f1f9.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -762,6 +839,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f9-1f1fc.svg" imageSource: "../../assets/twemoji/svg/1f1f9-1f1fc.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -772,6 +850,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f9-1f1ff.svg" imageSource: "../../assets/twemoji/svg/1f1f9-1f1ff.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -782,6 +861,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1f9-1f1f7.svg" imageSource: "../../assets/twemoji/svg/1f1f9-1f1f7.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -792,6 +872,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1fa-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1fa-1f1e6.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -802,6 +883,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1fa-1f1ec.svg" imageSource: "../../assets/twemoji/svg/1f1fa-1f1ec.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -812,6 +894,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1fa-1f1fe.svg" imageSource: "../../assets/twemoji/svg/1f1fa-1f1fe.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -822,6 +905,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1fb-1f1ea.svg" imageSource: "../../assets/twemoji/svg/1f1fb-1f1ea.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -832,6 +916,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1fb-1f1f3.svg" imageSource: "../../assets/twemoji/svg/1f1fb-1f1f3.svg"
selected: false selected: false
isToken: false
} }
ListElement { ListElement {
@ -842,6 +927,7 @@ QtObject {
category: qsTr("Other Fiat") category: qsTr("Other Fiat")
imageSource: "../../assets/twemoji/svg/1f1ff-1f1e6.svg" imageSource: "../../assets/twemoji/svg/1f1ff-1f1e6.svg"
selected: false selected: false
isToken: false
} }
} }

View File

@ -23,12 +23,12 @@ QtObject {
property bool isTenorWarningAccepted: !!accountSensitiveSettings ? accountSensitiveSettings.isTenorWarningAccepted : false property bool isTenorWarningAccepted: !!accountSensitiveSettings ? accountSensitiveSettings.isTenorWarningAccepted : false
property bool displayChatImages: !!accountSensitiveSettings ? accountSensitiveSettings.displayChatImages : false property bool displayChatImages: !!accountSensitiveSettings ? accountSensitiveSettings.displayChatImages : false
property string locale: Qt.locale().name property var locale: Qt.locale(localAppSettings.language)
// property string signingPhrase: !!walletModelInst ? walletModelInst.utilsView.signingPhrase : "" // property string signingPhrase: !!walletModelInst ? walletModelInst.utilsView.signingPhrase : ""
// property string gasPrice: !!walletModelInst ? walletModelInst.gasView.gasPrice : "0" // property string gasPrice: !!walletModelInst ? walletModelInst.gasView.gasPrice : "0"
// property string gasEthValue: !!walletModelInst ? walletModelInst.gasView.getGasEthValue : "0" // property string gasEthValue: !!walletModelInst ? walletModelInst.gasView.getGasEthValue : "0"
property CurrenciesStore currencyStore: CurrenciesStore { } property CurrenciesStore currencyStore: CurrenciesStore {}
property string currentCurrency: walletSection.currentCurrency property string currentCurrency: walletSection.currentCurrency
// property string defaultCurrency: !!walletModelInst ? walletModelInst.balanceView.defaultCurrency : "0" // property string defaultCurrency: !!walletModelInst ? walletModelInst.balanceView.defaultCurrency : "0"
// property string fiatValue: !!walletModelInst ? walletModelInst.balanceView.getFiatValue : "0" // property string fiatValue: !!walletModelInst ? walletModelInst.balanceView.getFiatValue : "0"

View File

@ -8,14 +8,14 @@ import "../../../app/AppLayouts/Profile/stores"
QtObject { QtObject {
id: root id: root
property CurrenciesStore currencyStore: CurrenciesStore { } property CurrenciesStore currencyStore: CurrenciesStore {}
property ProfileSectionStore profileSectionStore: ProfileSectionStore {} property ProfileSectionStore profileSectionStore: ProfileSectionStore {}
property var contactStore: profileSectionStore.contactsStore property var contactStore: profileSectionStore.contactsStore
property var mainModuleInst: mainModule property var mainModuleInst: mainModule
property var walletSectionTransactionsInst: walletSectionTransactions property var walletSectionTransactionsInst: walletSectionTransactions
property string locale: localAppSettings.language property var locale: Qt.locale(localAppSettings.language)
property string currentCurrency: walletSection.currentCurrency property string currentCurrency: walletSection.currentCurrency
property var allNetworks: networksModule.all property var allNetworks: networksModule.all
property var accounts: walletSectionAccounts.model property var accounts: walletSectionAccounts.model
@ -246,4 +246,25 @@ QtObject {
} }
} }
} }
function getTokenBalanceOnChain(selectedAccount, chainId: int, tokenSymbol: string) {
if (!selectedAccount) {
console.warn("selectedAccount invalid")
return undefined
}
const jsonObj = selectedAccount.getTokenBalanceOnChainAsJson(chainId, tokenSymbol)
if (jsonObj === "") {
console.warn("failed to get balance, returned json is empty")
return undefined
}
const obj = JSON.parse(jsonObj)
if (obj.error) {
console.warn("failed to get balance, json parse error: ", obj.error)
return undefined
}
return obj
}
} }

View File

@ -9,6 +9,7 @@ import utils 1.0
ColumnLayout { ColumnLayout {
id: root id: root
property var locale
property var store property var store
property var selectedAsset property var selectedAsset
property bool isLoading: false property bool isLoading: false
@ -20,7 +21,7 @@ ColumnLayout {
id: d id: d
function formatValue(value) { function formatValue(value) {
const precision = (value === 0 ? 2 : 0) const precision = (value === 0 ? 2 : 0)
return LocaleUtils.numberToLocaleString(value, precision) return LocaleUtils.numberToLocaleString(value, precision, root.locale)
} }
readonly property string fiatValue: { readonly property string fiatValue: {
if(!root.selectedAsset || !amountToReceive) if(!root.selectedAsset || !amountToReceive)

View File

@ -14,10 +14,11 @@ ColumnLayout {
property alias input: amountToSendInput property alias input: amountToSendInput
property var locale
property var selectedAsset property var selectedAsset
property bool isBridgeTx: false property bool isBridgeTx: false
property bool interactive: false property bool interactive: false
property double maxFiatBalance: -1 property var maxFiatBalance
property bool cryptoFiatFlipped: false property bool cryptoFiatFlipped: false
property string cryptoValueToSend: !cryptoFiatFlipped ? amountToSendInput.text : txtFiatBalance.text property string cryptoValueToSend: !cryptoFiatFlipped ? amountToSendInput.text : txtFiatBalance.text
property string currentCurrency property string currentCurrency
@ -35,7 +36,7 @@ ColumnLayout {
} }
function formatValue(value, precision) { function formatValue(value, precision) {
const precisionVal = !!precision ? precision : (value === 0 ? 2 : 0) const precisionVal = !!precision ? precision : (value === 0 ? 2 : 0)
return LocaleUtils.numberToLocaleString(value, precisionVal) return LocaleUtils.numberToLocaleString(value, precisionVal, root.locale)
} }
function getFiatValue(value) { function getFiatValue(value) {
if(!root.selectedAsset || !value) if(!root.selectedAsset || !value)
@ -58,7 +59,7 @@ ColumnLayout {
} }
onMaxFiatBalanceChanged: { onMaxFiatBalanceChanged: {
floatValidator.top = maxFiatBalance floatValidator.top = maxFiatBalance.amount
input.validate() input.validate()
} }
@ -84,7 +85,7 @@ ColumnLayout {
StatusFloatValidator { StatusFloatValidator {
id: floatValidator id: floatValidator
bottom: 0 bottom: 0
top: root.maxFiatBalance top: root.maxFiatBalance.amount
errorMessage: "" errorMessage: ""
} }
] ]

View File

@ -58,15 +58,18 @@ Item {
asset.name: token && token.symbol ? Style.png("tokens/%1".arg(token.symbol)) : "" asset.name: token && token.symbol ? Style.png("tokens/%1".arg(token.symbol)) : ""
asset.isImage: true asset.isImage: true
primaryText: token ? token.name : "" primaryText: token ? token.name : ""
secondaryText: token ? `${token.enabledNetworkBalance} ${token.symbol}` : "" secondaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkBalance, RootStore.locale) : ""
tertiaryText: token ? "%1 %2".arg(Utils.toLocaleString(token.enabledNetworkCurrencyBalance.toFixed(2), RootStore.locale, {"currency": true})).arg(RootStore.currencyStore.currentCurrency.toUpperCase()) : "" tertiaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkCurrencyBalance, RootStore.locale) : ""
balances: token && token.balances ? token.balances : null balances: token && token.balances ? token.balances : null
getNetworkColor: function(chainId){ getNetworkColor: function(chainId){
return RootStore.getNetworkColor(chainId) return RootStore.getNetworkColor(chainId)
} }
getNetworkIcon: function(chainId){ getNetworkIcon: function(chainId){
return RootStore.getNetworkIcon(chainId) return RootStore.getNetworkIcon(chainId)
} }
formatBalance: function(balance){
return LocaleUtils.currencyAmountToLocaleString(balance, RootStore.locale)
}
} }
enum GraphType { enum GraphType {
@ -225,7 +228,7 @@ Item {
fontColor: (Theme.palette.name === "dark") ? '#909090' : '#939BA1', fontColor: (Theme.palette.name === "dark") ? '#909090' : '#939BA1',
padding: 8, padding: 8,
callback: function(value, index, ticks) { callback: function(value, index, ticks) {
return LocaleUtils.numberToLocaleString(value) return LocaleUtils.numberToLocaleString(value, -1, RootStore.locale)
}, },
} }
}] }]
@ -264,23 +267,23 @@ Item {
InformationTile { InformationTile {
maxWidth: parent.width maxWidth: parent.width
primaryText: qsTr("Market Cap") primaryText: qsTr("Market Cap")
secondaryText: token && token.marketCap !== "" ? token.marketCap : "---" secondaryText: token && token.marketCap ? LocaleUtils.currencyAmountToLocaleString(token.marketCap, RootStore.locale) : "---"
} }
InformationTile { InformationTile {
maxWidth: parent.width maxWidth: parent.width
primaryText: qsTr("Day Low") primaryText: qsTr("Day Low")
secondaryText: token && token.lowDay !== "" ? token.lowDay : "---" secondaryText: token && token.lowDay ? LocaleUtils.currencyAmountToLocaleString(token.lowDay, RootStore.locale) : "---"
} }
InformationTile { InformationTile {
maxWidth: parent.width maxWidth: parent.width
primaryText: qsTr("Day High") primaryText: qsTr("Day High")
secondaryText: token && token.highDay ? token.highDay : "---" secondaryText: token && token.highDay ? LocaleUtils.currencyAmountToLocaleString(token.highDay, RootStore.locale) : "---"
} }
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
InformationTile { InformationTile {
readonly property string changePctHour: token ? token.changePctHour : "" readonly property string changePctHour: token ? token.changePctHour.toFixed(2) : ""
maxWidth: parent.width maxWidth: parent.width
primaryText: qsTr("Hour") primaryText: qsTr("Hour")
secondaryText: changePctHour ? "%1%".arg(changePctHour) : "---" secondaryText: changePctHour ? "%1%".arg(changePctHour) : "---"
@ -289,7 +292,7 @@ Item {
Theme.palette.successColor1 Theme.palette.successColor1
} }
InformationTile { InformationTile {
readonly property string changePctDay: token ? token.changePctDay : "" readonly property string changePctDay: token ? token.changePctDay.toFixed(2) : ""
maxWidth: parent.width maxWidth: parent.width
primaryText: qsTr("Day") primaryText: qsTr("Day")
secondaryText: changePctDay ? "%1%".arg(changePctDay) : "---" secondaryText: changePctDay ? "%1%".arg(changePctDay) : "---"
@ -298,7 +301,7 @@ Item {
Theme.palette.successColor1 Theme.palette.successColor1
} }
InformationTile { InformationTile {
readonly property string changePct24hour: token ? token.changePct24hour : "" readonly property string changePct24hour: token ? token.changePct24hour.toFixed(2) : ""
maxWidth: parent.width maxWidth: parent.width
primaryText: qsTr("24 Hours") primaryText: qsTr("24 Hours")
secondaryText: changePct24hour ? "%1%".arg(changePct24hour) : "---" secondaryText: changePct24hour ? "%1%".arg(changePct24hour) : "---"

View File

@ -18,6 +18,7 @@ Item {
property var account property var account
property bool assetDetailsLaunched: false property bool assetDetailsLaunched: false
property var locale
signal assetClicked(var token) signal assetClicked(var token)
@ -43,8 +44,8 @@ Item {
delegate: TokenDelegate { delegate: TokenDelegate {
objectName: "AssetView_TokenListItem_" + symbol objectName: "AssetView_TokenListItem_" + symbol
readonly property string balance: enabledNetworkBalance // Needed for the tests locale: root.locale
currentCurrencySymbol: RootStore.currencyStore.currentCurrencySymbol readonly property string balance: "%1".arg(enabledNetworkBalance.amount) // Needed for the tests
width: ListView.view.width width: ListView.view.width
onClicked: { onClicked: {
RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency) RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency)

View File

@ -91,13 +91,14 @@ Item {
objectName: model.chainId objectName: model.chainId
property double amountToSend: 0 property double amountToSend: 0
property int routeOnNetwork: 0 property int routeOnNetwork: 0
property string tokenBalanceOnChain: selectedAccount && selectedAccount!== undefined && selectedAsset!== undefined ? selectedAccount.getTokenBalanceOnChain(model.chainId, selectedAsset.symbol) : "" property bool tokenBalanceOnChainValid: selectedAccount && selectedAccount !== undefined && selectedAsset !== undefined
property var tokenBalanceOnChain: tokenBalanceOnChainValid ? root.store.getTokenBalanceOnChain(selectedAccount, model.chainId, selectedAsset.symbol) : undefined
property var hasGas: selectedAccount.hasGas(model.chainId, model.nativeCurrencySymbol, requiredGasInEth) property var hasGas: selectedAccount.hasGas(model.chainId, model.nativeCurrencySymbol, requiredGasInEth)
primaryText: model.chainName primaryText: model.chainName
secondaryText: (parseFloat(tokenBalanceOnChain) === 0 && root.amountToSend !== 0) ? secondaryText: (tokenBalanceOnChain.amount === 0) && root.amountToSend !== 0 ?
qsTr("No Balance") : !hasGas ? qsTr("No Gas") : advancedInputText qsTr("No Balance") : !hasGas ? qsTr("No Gas") : advancedInputText
tertiaryText: root.errorMode && parseFloat(advancedInputText) !== 0 && advancedInput.valid ? qsTr("EXCEEDS SEND AMOUNT"): qsTr("BALANCE: ") + LocaleUtils.numberToLocaleString(parseFloat(tokenBalanceOnChain)) tertiaryText: root.errorMode && parseFloat(advancedInputText) !== 0 && advancedInput.valid ? qsTr("EXCEEDS SEND AMOUNT"): qsTr("BALANCE: ") + LocaleUtils.currencyAmountToLocaleString(tokenBalanceOnChain, root.store.locale)
locked: store.lockedInAmounts.findIndex(lockedItem => lockedItem !== undefined && lockedItem.chainID === model.chainId) !== -1 locked: store.lockedInAmounts.findIndex(lockedItem => lockedItem !== undefined && lockedItem.chainID === model.chainId) !== -1
preCalculatedAdvancedText: { preCalculatedAdvancedText: {
let index = store.lockedInAmounts.findIndex(lockedItem => lockedItem!== undefined && lockedItem.chainID === model.chainId) let index = store.lockedInAmounts.findIndex(lockedItem => lockedItem!== undefined && lockedItem.chainID === model.chainId)
@ -106,8 +107,8 @@ Item {
} }
else return LocaleUtils.numberToLocaleString(fromNetwork.amountToSend) else return LocaleUtils.numberToLocaleString(fromNetwork.amountToSend)
} }
maxAdvancedValue: parseFloat(tokenBalanceOnChain) maxAdvancedValue: tokenBalanceOnChain.amount
state: tokenBalanceOnChain === 0 || !hasGas ? state: tokenBalanceOnChain.amount === 0 || !hasGas ?
"unavailable" : "unavailable" :
(root.errorMode || !advancedInput.valid) && (parseFloat(advancedInputText) !== 0) ? "error" : "default" (root.errorMode || !advancedInput.valid) && (parseFloat(advancedInputText) !== 0) ? "error" : "default"
cardIcon.source: Style.svg(model.iconUrl) cardIcon.source: Style.svg(model.iconUrl)

View File

@ -126,8 +126,9 @@ RowLayout {
rightPadding: 5 rightPadding: 5
implicitWidth: 150 implicitWidth: 150
title: chainName title: chainName
subTitle: selectedAccount && selectedAccount!== undefined && selectedAsset!== undefined ? property bool tokenBalanceOnChainValid: selectedAccount && selectedAccount !== undefined && selectedAsset !== undefined
selectedAccount.getTokenBalanceOnChain(chainId, selectedAsset.symbol) : "" property var tokenBalanceOnChain: tokenBalanceOnChainValid ? root.store.getTokenBalanceOnChain(selectedAccount, chainId, selectedAsset.symbol) : undefined
subTitle: tokenBalanceOnChain ? LocaleUtils.currencyAmountToLocaleString(tokenBalanceOnChain, root.store.locale) : "N/A"
statusListItemSubTitle.color: Theme.palette.primaryColor1 statusListItemSubTitle.color: Theme.palette.primaryColor1
asset.width: 32 asset.width: 32
asset.height: 32 asset.height: 32

View File

@ -22,6 +22,7 @@ Item {
implicitHeight: visible ? accountSelectionTabBar.height + stackLayout.height + Style.current.bigPadding: 0 implicitHeight: visible ? accountSelectionTabBar.height + stackLayout.height + Style.current.bigPadding: 0
property var store property var store
property var locale
signal contactSelected(string address, int type) signal contactSelected(string address, int type)
@ -152,7 +153,7 @@ Item {
objectName: model.name objectName: model.name
height: visible ? 64 : 0 height: visible ? 64 : 0
title: !!model.name ? model.name : "" title: !!model.name ? model.name : ""
subTitle: "%1 %2".arg(LocaleUtils.numberToLocaleString(model.currencyBalance)).arg(store.currentCurrency.toUpperCase()) subTitle: LocaleUtils.currencyAmountToLocaleString(model.currencyBalance, root.locale)
asset.emoji: !!model.emoji ? model.emoji: "" asset.emoji: !!model.emoji ? model.emoji: ""
asset.color: model.color asset.color: model.color
asset.name: !model.emoji ? "filled-account": "" asset.name: !model.emoji ? "filled-account": ""

View File

@ -14,8 +14,8 @@ import "../controls"
Rectangle { Rectangle {
id: root id: root
property var locale
property var assets: [] property var assets: []
property string currentCurrencySymbol
signal tokenSelected(var selectedToken) signal tokenSelected(var selectedToken)
property var searchTokenSymbolByAddressFn: function (address) { property var searchTokenSymbolByAddressFn: function (address) {
return "" return ""
@ -56,7 +56,7 @@ Rectangle {
} }
delegate: TokenBalancePerChainDelegate { delegate: TokenBalancePerChainDelegate {
width: ListView.view.width width: ListView.view.width
currentCurrencySymbol: root.currentCurrencySymbol locale: root.locale
getNetworkIcon: root.getNetworkIcon getNetworkIcon: root.getNetworkIcon
onTokenSelected: root.tokenSelected(selectedToken) onTokenSelected: root.tokenSelected(selectedToken)
} }

View File

@ -11,6 +11,11 @@ QtObject {
return num.toString().split('.')[1].length return num.toString().split('.')[1].length
} }
function stripTrailingZeroes(numStr, locale) {
let regEx = locale.decimalPoint == "." ? /(\.[0-9]*[1-9])0+$|\.0*$/ : /(\,[0-9]*[1-9])0+$|\,0*$/
return numStr.replace(regEx, '$1')
}
function numberToLocaleString(num, precision = -1, locale = null) { function numberToLocaleString(num, precision = -1, locale = null) {
locale = locale || Qt.locale() locale = locale || Qt.locale()
@ -19,4 +24,23 @@ QtObject {
return num.toLocaleString(locale, 'f', precision) return num.toLocaleString(locale, 'f', precision)
} }
function currencyAmountToLocaleString(currencyAmount, locale) {
if (!locale) {
console.log("Unspecified locale for: " + JSON.stringify(currencyAmount))
locale = Qt.locale()
}
if (typeof(currencyAmount) !== "object") {
console.log("Wrong type for currencyAmount: " + JSON.stringify(currencyAmount))
return NaN
}
var amountStr = numberToLocaleString(currencyAmount.amount, currencyAmount.displayDecimals, locale)
if (currencyAmount.stripTrailingZeroes) {
amountStr = stripTrailingZeroes(amountStr, locale)
}
if (currencyAmount.symbol) {
amountStr = "%1 %2".arg(amountStr).arg(currencyAmount.symbol)
}
return amountStr
}
} }

View File

@ -88,7 +88,11 @@ QtObject {
} }
function toLocaleString(val, locale, options) { function toLocaleString(val, locale, options) {
return NumberPolyFill.toLocaleString(val, locale, options) if (typeof(val) === "object") {
console.log("Wrong type for val: " + JSON.stringify(val))
return NaN
}
return NumberPolyFill.toLocaleString(val, locale, options)
} }
function isOnlyEmoji(inputText) { function isOnlyEmoji(inputText) {

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 883f9677c593494eceadef004932c0434575a5be Subproject commit 77a56e2b930c52709d462aa5add764014cc16a09