feat(@desktop/wallet) implement price cache

This commit is contained in:
Dario Gabriel Lipicar 2023-01-19 10:09:02 -03:00 committed by dlipicar
parent 53ee992c25
commit be26dc049b
5 changed files with 53 additions and 28 deletions

View File

@ -11,6 +11,11 @@ type TimedCache*[T] = Table[string, Value[T]]
proc newTimedCache*[T](): TimedCache[T] = initTable[string, Value[T]]()
proc init*[T](self: var TimedCache[T], values: Table[string, T]) =
self.clear()
for cacheKey, value in values:
self[cacheKey].value = value
proc getTimestamp[T](self: TimedCache[T], cacheKey: string): DateTime = self[cacheKey].timestamp
proc isCached*[T](self: TimedCache[T], cacheKey: string, duration=initDuration(minutes = 5)): bool =

View File

@ -46,7 +46,7 @@ QtObject:
)
return self.fiatCurrencyFormatCache[symbol]
proc getTokenCurrencyFormat(self: Service, symbol: string, allowFetching: bool): CurrencyFormatDto =
proc getTokenCurrencyFormat(self: Service, symbol: string): CurrencyFormatDto =
if self.tokenCurrencyFormatCache.isCached(symbol):
return self.tokenCurrencyFormatCache.get(symbol)
@ -61,21 +61,19 @@ QtObject:
)
updateCache = true
else:
let price = (if allowFetching: self.tokenService.getTokenPrice(symbol, DECIMALS_CALCULATION_CURRENCY) else :
self.tokenService.getCachedTokenPrice(symbol, DECIMALS_CALCULATION_CURRENCY))
let price = self.tokenService.getCachedTokenPrice(symbol, DECIMALS_CALCULATION_CURRENCY, true)
result = CurrencyFormatDto(
symbol: symbol,
displayDecimals: getTokenDisplayDecimals(price),
stripTrailingZeroes: true
)
updateCache = (if allowFetching: true else:
self.tokenService.isCachedTokenPriceRecent(symbol, DECIMALS_CALCULATION_CURRENCY))
updateCache = self.tokenService.isCachedTokenPriceRecent(symbol, DECIMALS_CALCULATION_CURRENCY)
if updateCache:
self.tokenCurrencyFormatCache.set(symbol, result)
proc getCurrencyFormat*(self: Service, symbol: string, allowFetching: bool = true): CurrencyFormatDto =
proc getCurrencyFormat*(self: Service, symbol: string): CurrencyFormatDto =
if self.isCurrencyFiat(symbol):
return self.getFiatCurrencyFormat(symbol)
else:
return self.getTokenCurrencyFormat(symbol, allowFetching)
return self.getTokenCurrencyFormat(symbol)

View File

@ -50,6 +50,8 @@ QtObject:
priceCache: TimedCache[float64]
proc updateCachedTokenPrice(self: Service, crypto: string, fiat: string, price: float64)
proc initTokenPrices(self: Service, prices: Table[string, Table[string, float64]])
proc jsonToPricesMap(node: JsonNode): Table[string, Table[string, float64]]
proc delete*(self: Service) =
self.QObject.delete
@ -69,6 +71,9 @@ QtObject:
proc init*(self: Service) =
try:
let response = backend.getCachedPrices()
self.initTokenPrices(jsonToPricesMap(response.result))
let networks = self.networkService.getNetworks()
for network in networks:
@ -96,12 +101,6 @@ QtObject:
error "error: ", errDesription
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 =
try:
for token in self.tokens[network.chainId]:
@ -142,21 +141,33 @@ QtObject:
let cryptoKey = renameSymbol(crypto)
return CRYPTO_SUB_UNITS_TO_FACTOR.getOrDefault(cryptoKey, (cryptoKey, 1.0))
proc jsonToPricesMap(node: JsonNode) : Table[string, Table[string, float64]] =
result = initTable[string, Table[string, float64]]()
for (symbol, pricePerCurrency) in node.pairs:
result[symbol] = initTable[string, float64]()
for (currency, price) in pricePerCurrency.pairs:
result[symbol][currency] = price.getFloat
proc initTokenPrices(self: Service, prices: Table[string, Table[string, float64]]) =
var cacheTable: Table[string, float64]
for token, pricesPerCurrency in prices:
for currency, price in pricesPerCurrency:
let cacheKey = getTokenPriceCacheKey(token, currency)
cacheTable[cacheKey] = price
self.priceCache.init(cacheTable)
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 isCachedTokenPriceRecent*(self: Service, crypto: string, fiat: string): bool =
let (cryptoKey, _) = getCryptoKeyAndFactor(crypto)
let cacheKey = getTokenPriceCacheKey(cryptoKey, fiat)
return self.priceCache.isCached(cacheKey)
proc getCachedTokenPrice*(self: Service, crypto: string, fiat: string): float64 =
let (cryptoKey, factor) = getCryptoKeyAndFactor(crypto)
let cacheKey = getTokenPriceCacheKey(cryptoKey, fiat)
if self.priceCache.hasKey(cacheKey):
return self.priceCache.get(cacheKey) * factor
else:
return 0.0
proc getTokenPrice*(self: Service, crypto: string, fiat: string): float64 =
let fiatKey = renameSymbol(fiat)
let (cryptoKey, factor) = getCryptoKeyAndFactor(crypto)
@ -168,10 +179,7 @@ QtObject:
try:
let response = backend.fetchPrices(@[cryptoKey], @[fiatKey])
for (symbol, pricePerCurrency) in response.result.pairs:
prices[symbol] = initTable[string, float]()
for (currency, price) in pricePerCurrency.pairs:
prices[symbol][currency] = price.getFloat
let prices = jsonToPricesMap(response.result)
self.updateCachedTokenPrice(cryptoKey, fiatKey, prices[cryptoKey][fiatKey])
return prices[cryptoKey][fiatKey] * factor
@ -180,6 +188,17 @@ QtObject:
error "error: ", errDesription
return 0.0
proc getCachedTokenPrice*(self: Service, crypto: string, fiat: string, fetchIfNotPresent: bool = false): float64 =
let (cryptoKey, factor) = getCryptoKeyAndFactor(crypto)
let cacheKey = getTokenPriceCacheKey(cryptoKey, fiat)
if self.priceCache.hasKey(cacheKey):
return self.priceCache.get(cacheKey) * factor
elif fetchIfNotPresent:
return self.getTokenPrice(crypto, fiat)
else:
return 0.0
proc updateCachedTokenPrice(self: Service, crypto: string, fiat: string, price: float64) =
let cacheKey = getTokenPriceCacheKey(crypto, fiat)
self.priceCache.set(cacheKey, price)

View File

@ -102,6 +102,9 @@ rpc(fetchPrices, "wallet"):
symbols: seq[string]
currencies: seq[string]
rpc(getCachedPrices, "wallet"):
discard
rpc(generateAccountWithDerivedPath, "accounts"):
password: string
name: string

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit cedc1a5fd1b2fc29d3e2c5001c27046f541fbcf9
Subproject commit ea46779e98708616201728e422253564809043dc