Skip to content

Commit

Permalink
feat: cache historic price in frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
lukicenturi authored and kelsos committed Apr 20, 2023
1 parent 14499c4 commit fbce0f9
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 68 deletions.
1 change: 1 addition & 0 deletions frontend/app/.eslintrc-auto-import.json
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@
"useGeneralSettingsStore": true,
"useGeolocation": true,
"useGraph": true,
"useHistoricCachePriceStore": true,
"useHistoryApi": true,
"useHistoryAutoRefresh": true,
"useHistoryEventFilter": true,
Expand Down
2 changes: 2 additions & 0 deletions frontend/app/src/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ declare global {
const useGeneralSettingsStore: typeof import('./store/settings/general')['useGeneralSettingsStore']
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
const useGraph: typeof import('./composables/graphs')['useGraph']
const useHistoricCachePriceStore: typeof import('./store/prices/historic')['useHistoricCachePriceStore']
const useHistoryApi: typeof import('./composables/api/history/index')['useHistoryApi']
const useHistoryAutoRefresh: typeof import('./composables/history/auto-refresh')['useHistoryAutoRefresh']
const useHistoryEventFilter: typeof import('./composables/filters/events')['useHistoryEventFilter']
Expand Down Expand Up @@ -1053,6 +1054,7 @@ declare module 'vue' {
readonly useGeneralSettingsStore: UnwrapRef<typeof import('./store/settings/general')['useGeneralSettingsStore']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
readonly useGraph: UnwrapRef<typeof import('./composables/graphs')['useGraph']>
readonly useHistoricCachePriceStore: UnwrapRef<typeof import('./store/prices/historic')['useHistoricCachePriceStore']>
readonly useHistoryApi: UnwrapRef<typeof import('./composables/api/history/index')['useHistoryApi']>
readonly useHistoryAutoRefresh: UnwrapRef<typeof import('./composables/history/auto-refresh')['useHistoryAutoRefresh']>
readonly useHistoryEventFilter: UnwrapRef<typeof import('./composables/filters/events')['useHistoryEventFilter']>
Expand Down
64 changes: 19 additions & 45 deletions frontend/app/src/components/display/amount/AmountDisplay.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { BigNumber } from '@rotki/common';
import { type ComputedRef, type Ref } from 'vue';
import { type ComputedRef } from 'vue';
import { or } from '@vueuse/math';
import { displayAmountFormatter } from '@/data/amount_formatter';
import { CURRENCY_USD, type Currency, useCurrencies } from '@/types/currencies';
import { type RoundingMode } from '@/types/frontend-settings';
Expand Down Expand Up @@ -65,8 +66,6 @@ const {
timestamp
} = toRefs(props);
const evaluating: Ref<boolean> = ref(false);
const {
currency,
currencySymbol: currentCurrency,
Expand All @@ -77,7 +76,8 @@ const { scrambleData, shouldShowAmount, scrambleMultiplier } = storeToRefs(
useSessionSettingsStore()
);
const { exchangeRate, assetPrice, getHistoricPrice } = useBalancePricesStore();
const { exchangeRate, assetPrice, isAssetPriceInCurrentCurrency } =
useBalancePricesStore();
const {
abbreviateNumber,
Expand All @@ -88,48 +88,16 @@ const {
valueRoundingMode
} = storeToRefs(useFrontendSettingsStore());
const { isAssetPriceInCurrentCurrency } = useBalancePricesStore();
const isCurrentCurrency = isAssetPriceInCurrentCurrency(priceAsset);
const { findCurrency } = useCurrencies();
const priceHistoricRate = asyncComputed(
async () => {
assert(isDefined(priceAsset));
return await getHistoricPrice({
fromAsset: get(priceAsset),
toAsset: get(currentCurrency),
timestamp: get(timestamp)
});
},
One.negated(),
{
lazy: true,
evaluating,
onError(e: any) {
logger.error(e);
}
}
);
const { historicPriceInCurrentCurrency, isPending } =
useHistoricCachePriceStore();
const historicExchangeRate = asyncComputed(
async () => {
assert(isDefined(sourceCurrency));
return await getHistoricPrice({
fromAsset: get(sourceCurrency),
toAsset: get(currentCurrency),
timestamp: get(timestamp)
});
},
One.negated(),
{
lazy: true,
evaluating,
onError(e: any) {
logger.error(e);
}
}
const evaluating = or(
isPending(`${get(priceAsset)}#${get(timestamp)}`),
isPending(`${get(sourceCurrency)}#${get(timestamp)}`)
);
const latestFiatValue: ComputedRef<BigNumber> = computed(() => {
Expand Down Expand Up @@ -160,6 +128,7 @@ const internalValue: ComputedRef<BigNumber> = computed(() => {
const currentCurrencyVal = get(currentCurrency);
const priceAssetVal = get(priceAsset);
const isCurrentCurrencyVal = get(isCurrentCurrency);
const timestampVal = get(timestamp);
// If `priceAsset` is defined, it means we will not use value from `value`, but calculate it ourselves from the price of `priceAsset`
if (priceAssetVal) {
Expand All @@ -174,8 +143,10 @@ const internalValue: ComputedRef<BigNumber> = computed(() => {
}
}
if (get(timestamp) > 0 && get(amount) && get(priceAsset)) {
const assetHistoricRate = get(priceHistoricRate);
if (timestampVal > 0 && get(amount) && priceAssetVal) {
const assetHistoricRate = get(
historicPriceInCurrentCurrency(priceAssetVal, timestampVal)
);
if (assetHistoricRate.isPositive()) {
return get(amount).multipliedBy(assetHistoricRate);
}
Expand All @@ -185,8 +156,11 @@ const internalValue: ComputedRef<BigNumber> = computed(() => {
if (sourceCurrencyVal !== currentCurrencyVal) {
let calculatedValue = get(latestFiatValue);
if (get(timestamp) > 0) {
const historicRate = get(historicExchangeRate);
if (timestampVal > 0) {
const historicRate = get(
historicPriceInCurrentCurrency(sourceCurrencyVal, timestampVal)
);
if (historicRate.isPositive()) {
calculatedValue = get(value).multipliedBy(historicRate);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const showBalance = computed<boolean>(() => {
});
const eventAsset = computed(() => get(event).asset);
const symbol = assetSymbol(eventAsset);
const symbol = assetSymbol(eventAsset);
const extraDataPanel: Ref<number[]> = ref([]);
</script>
<template>
Expand All @@ -44,6 +44,7 @@ const extraDataPanel: Ref<number[]> = ref([]);
</div>
<div>
<amount-display
:key="event.timestamp"
:amount="event.balance.amount"
:value="event.balance.usdValue"
:price-asset="event.asset"
Expand Down
23 changes: 22 additions & 1 deletion frontend/app/src/composables/api/balances/price.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import {
} from '@/services/utils';
import { type SupportedCurrency } from '@/types/currencies';
import { type PriceOracle } from '@/types/price-oracle';
import { type OracleCacheMeta } from '@/types/prices';
import {
type HistoricPricesPayload,
type OracleCacheMeta
} from '@/types/prices';
import { type PendingTask } from '@/types/task';

export const usePriceApi = () => {
Expand Down Expand Up @@ -88,6 +91,23 @@ export const usePriceApi = () => {
return handleResponse(response);
};

const queryHistoricalRates = async (
payload: HistoricPricesPayload
): Promise<PendingTask> => {
const response = await api.instance.post<ActionResult<PendingTask>>(
'/assets/prices/historical',
snakeCaseTransformer({
asyncQuery: true,
...payload
}),
{
validateStatus: validWithSessionAndExternalService
}
);

return handleResponse(response);
};

const queryPrices = async (
assets: string[],
targetAsset: string,
Expand Down Expand Up @@ -131,6 +151,7 @@ export const usePriceApi = () => {
queryPrices,
queryFiatExchangeRates,
queryHistoricalRate,
queryHistoricalRates,
getPriceCache,
createPriceCache,
deletePriceCache
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/src/locales/cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
},
"historic_fetch_price": {
"task": {
"description": "在 {date} 从 {fromAsset} 获取利率到 {toAsset}",
"description": "在 {date} 从 {fromAsset} 获取利率到 {toAsset} | 获取 {count} 对到 {toAsset} 的速率",
"title": "获取转化率"
}
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@
},
"historic_fetch_price": {
"task": {
"description": "Fetching rate from {fromAsset} to {toAsset} on {date}",
"description": "Fetching rate from {fromAsset} to {toAsset} on {date} | Fetching rates for {count} pairs to {toAsset}",
"title": "Fetching conversion rate"
}
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
},
"historic_fetch_price": {
"task": {
"description": "Fetching rate from {fromAsset} to {toAsset} on {date}",
"description": "Fetching rate from {fromAsset} to {toAsset} on {date} | Fetching rates for {count} pairs to {toAsset}",
"title": "Fetching conversion rate"
}
},
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/src/locales/gr.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@
},
"historic_fetch_price": {
"task": {
"description": "Fetching rate from {fromAsset} to {toAsset} on {date}",
"description": "Fetching rate from {fromAsset} to {toAsset} on {date} | Fetching rates for {count} pairs to {toAsset}",
"title": "Fetching conversion rate"
}
},
Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/store/balances/prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const useBalancePricesStore = defineStore('balances/prices', () => {

const { awaitTask, isTaskRunning } = useTaskStore();
const { notify } = useNotificationsStore();
const { t } = useI18n();
const { t, tc } = useI18n();
const {
getPriceCache,
createPriceCache,
Expand Down Expand Up @@ -149,8 +149,9 @@ export const useBalancePricesStore = defineStore('balances/prices', () => {
title: t(
'actions.balances.historic_fetch_price.task.title'
).toString(),
description: t(
description: tc(
'actions.balances.historic_fetch_price.task.description',
1,
{
fromAsset,
toAsset,
Expand Down
Loading

0 comments on commit fbce0f9

Please sign in to comment.