mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-03-07 15:58:07 +01:00
142 lines
4.4 KiB
TypeScript
142 lines
4.4 KiB
TypeScript
import { A, D, pipe } from '@mobily/ts-belt';
|
|
import { differenceInMinutes, eachMinuteOfInterval, fromUnixTime, getUnixTime } from 'date-fns';
|
|
|
|
import { BaseCurrencyCode } from '@suite-common/suite-config';
|
|
import { BigNumber } from '@trezor/utils/src/bigNumber';
|
|
|
|
import {
|
|
AccountHistoryBalancePoint,
|
|
AccountWithBalanceHistory,
|
|
FiatGraphPoint,
|
|
FiatGraphPointWithCryptoBalance,
|
|
} from './types';
|
|
|
|
export const getDataStepInMinutes = ({
|
|
startOfTimeFrameDate,
|
|
endOfTimeFrameDate,
|
|
numberOfPoints,
|
|
}: {
|
|
startOfTimeFrameDate: Date;
|
|
endOfTimeFrameDate: Date;
|
|
numberOfPoints: number;
|
|
}): number => {
|
|
const differenceMinutes = differenceInMinutes(endOfTimeFrameDate, startOfTimeFrameDate);
|
|
|
|
return Math.ceil(differenceMinutes / numberOfPoints);
|
|
};
|
|
|
|
export const getTimestampsInTimeFrame = (
|
|
startOfTimeFrameDate: Date,
|
|
endOfTimeFrameDate: Date,
|
|
numberOfPoints: number,
|
|
) => {
|
|
const stepInMinutes = getDataStepInMinutes({
|
|
startOfTimeFrameDate,
|
|
endOfTimeFrameDate,
|
|
numberOfPoints,
|
|
});
|
|
|
|
const intervalEndDate = fromUnixTime(getUnixTime(endOfTimeFrameDate));
|
|
|
|
const datesInRange = eachMinuteOfInterval(
|
|
{
|
|
start: startOfTimeFrameDate,
|
|
end: intervalEndDate,
|
|
},
|
|
{
|
|
step: stepInMinutes,
|
|
},
|
|
);
|
|
const datesInRangeUnixTime = A.map(datesInRange, date => getUnixTime(date));
|
|
|
|
return datesInRangeUnixTime as number[];
|
|
};
|
|
|
|
export const mapCryptoBalanceMovementToFixedTimeFrame = ({
|
|
balanceHistory,
|
|
fiatRates,
|
|
fiatCurrency,
|
|
}: {
|
|
balanceHistory: AccountHistoryBalancePoint[];
|
|
fiatRates: Array<{
|
|
time: number;
|
|
rates: {
|
|
[key: string]: number | undefined;
|
|
};
|
|
}>;
|
|
fiatCurrency: BaseCurrencyCode;
|
|
}): readonly FiatGraphPointWithCryptoBalance[] =>
|
|
pipe(
|
|
fiatRates,
|
|
A.map(fiatRatePoint => {
|
|
let fiatRate = fiatRatePoint.rates[fiatCurrency] ?? 0;
|
|
// for some tokens we could get fiat rate -1, which is not valid
|
|
fiatRate = fiatRate < 0 ? 0 : fiatRate;
|
|
const rateDate = fromUnixTime(fiatRatePoint.time);
|
|
|
|
if (fiatRate === 0) {
|
|
// return early if the fiat rate is 0 to save resources on further calculations (find and BigNumber are slow)
|
|
return {
|
|
date: rateDate,
|
|
cryptoBalance: '0',
|
|
value: 0,
|
|
};
|
|
}
|
|
|
|
// Find the latest account balance before or at the fiatRatePoint time
|
|
const accountBalancePoint = balanceHistory.find(
|
|
point => point.time >= fiatRatePoint.time,
|
|
);
|
|
|
|
const cryptoBalance = accountBalancePoint
|
|
? new BigNumber(accountBalancePoint.cryptoBalance)
|
|
: new BigNumber('0');
|
|
|
|
return {
|
|
date: rateDate,
|
|
cryptoBalance: cryptoBalance.toFixed(),
|
|
// We display only two decimal places in the graph. So if there is any value lower than that, we want to round it.
|
|
value: Number(cryptoBalance.multipliedBy(fiatRate).toFixed(2)),
|
|
};
|
|
}),
|
|
);
|
|
|
|
export const mergeMultipleFiatBalanceHistories = (
|
|
fiatBalancesHistories: readonly (readonly FiatGraphPointWithCryptoBalance[])[],
|
|
): readonly FiatGraphPoint[] =>
|
|
pipe(
|
|
fiatBalancesHistories,
|
|
A.flat,
|
|
A.groupBy(fiatBalancePoint => getUnixTime(fiatBalancePoint.date)),
|
|
D.mapWithKey((timestamp, fiatBalancePoints) => {
|
|
const fiatBalance = fiatBalancePoints
|
|
? A.reduce(
|
|
fiatBalancePoints,
|
|
0,
|
|
(acc, fiatBalancePoint) => acc + fiatBalancePoint.value,
|
|
)
|
|
: 0;
|
|
|
|
return {
|
|
date: fromUnixTime(timestamp),
|
|
value: fiatBalance,
|
|
};
|
|
}),
|
|
D.values,
|
|
);
|
|
|
|
export const findOldestBalanceMovementTimestamp = (
|
|
accountsWithBalanceHistory: AccountWithBalanceHistory[],
|
|
): number => {
|
|
const allOldestTimestamps: number[] = [];
|
|
|
|
accountsWithBalanceHistory.forEach(account => {
|
|
const oldestTimestamp = account.balanceHistory[0]?.time;
|
|
if (oldestTimestamp) {
|
|
allOldestTimestamps.push(oldestTimestamp);
|
|
}
|
|
});
|
|
|
|
return Math.min(...allOldestTimestamps);
|
|
};
|