Skip to content

Commit

Permalink
chore(suite): store historic rates for remembered wallet to storage
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamSchinzel committed May 15, 2024
1 parent 317c196 commit 9e0bee6
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 12 deletions.
28 changes: 23 additions & 5 deletions packages/suite/src/actions/suite/storageActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { cloneObject } from '@trezor/utils';

import { Discovery, FormDraftKeyPrefix } from '@suite-common/wallet-types';
import { notificationsActions } from '@suite-common/toast-notifications';
import { getFormDraftKey } from '@suite-common/wallet-utils';
import { selectHistoricRatesByTransactions, getFormDraftKey } from '@suite-common/wallet-utils';
import { FormDraftPrefixKeyValues } from '@suite-common/wallet-constants';
import { selectDevices, deviceActions } from '@suite-common/wallet-core';

Expand All @@ -16,7 +16,7 @@ import {
} from 'src/utils/suite/storage';
import type { AppState, Dispatch, GetState, TrezorDevice } from 'src/types/suite';
import type { Account, Network } from 'src/types/wallet';
import type { FormState } from '@suite-common/wallet-types';
import type { FormState, RatesByTimestamps } from '@suite-common/wallet-types';
import type { Trade } from 'src/types/wallet/coinmarketCommonTypes';
import type { PreloadStoreAction } from 'src/support/suite/preloadStore';
import { GraphData } from 'src/types/wallet/graph';
Expand All @@ -29,7 +29,6 @@ import { MetadataState } from '@suite-common/metadata-types';
export type StorageAction = NonNullable<PreloadStoreAction>;
export type StorageLoadAction = Extract<StorageAction, { type: typeof STORAGE.LOAD }>;

// send form drafts start
export const saveDraft = async (formState: FormState, accountKey: string) => {
if (!(await db.isAccessible())) return;

Expand Down Expand Up @@ -100,8 +99,6 @@ export const saveCoinjoinDebugSettings = () => async (_dispatch: Dispatch, getSt
db.addItem('coinjoinDebugSettings', debug || {}, 'debug', true);
};

// send form drafts end

export const saveFormDraft = async (key: string, draft: FieldValues) => {
if (!(await db.isAccessible())) return;

Expand Down Expand Up @@ -164,6 +161,12 @@ const removeAccountGraph = async (account: Account) => {
]);
};

export const removeAccountHistoricRates = async (accountKey: string) => {
if (!(await db.isAccessible())) return;

return db.removeItemByPK('historicRates', accountKey);
};

export const removeAccountWithDependencies = (getState: GetState) => (account: Account) =>
Promise.all([
...FormDraftPrefixKeyValues.map(prefix => removeAccountFormDraft(prefix, account.key)),
Expand All @@ -172,6 +175,7 @@ export const removeAccountWithDependencies = (getState: GetState) => (account: A
removeAccountGraph(account),
removeCoinjoinAccount(account.key, getState()),
removeAccount(account),
removeAccountHistoricRates(account.key),
]);

export const forgetDevice = (device: TrezorDevice) => async (_: Dispatch, getState: GetState) => {
Expand Down Expand Up @@ -214,6 +218,18 @@ export const saveGraph = async (graphData: GraphData[]) => {
return db.addItems('graph', graphData, true);
};

export const saveAccountHistoricRates =
(accountKey: string, historicRates: RatesByTimestamps) =>
async (_dispatch: Dispatch, getState: GetState) => {
if (!(await db.isAccessible())) return Promise.resolve();
const allTxs = getState().wallet.transactions.transactions;
const accTxs = allTxs[accountKey] || [];

const accHistoricRates = selectHistoricRatesByTransactions(historicRates, accTxs);

return db.addItem('historicRates', accHistoricRates, accountKey, true);
};

export const saveAccountTransactions =
(account: Account) => async (_dispatch: Dispatch, getState: GetState) => {
if (!(await db.isAccessible())) return Promise.resolve();
Expand Down Expand Up @@ -244,6 +260,7 @@ export const rememberDevice =
const discovery = wallet.discovery
.filter(d => d.deviceState === device.state)
.map(serializeDiscovery);
const historicRates = wallet.fiat.historic;

const accountPromises = accounts.reduce(
(promises, account) =>
Expand All @@ -252,6 +269,7 @@ export const rememberDevice =
dispatch(saveAccountTransactions(account)),
dispatch(saveAccountDraft(account)),
dispatch(saveCoinjoinAccount(account.key)),
dispatch(saveAccountHistoricRates(account.key, historicRates)),
],
FormDraftPrefixKeyValues.map(prefix =>
dispatch(saveAccountFormDraft(prefix, account.key)),
Expand Down
13 changes: 12 additions & 1 deletion packages/suite/src/middlewares/wallet/storageMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
selectAccountByKey,
deviceActions,
selectDeviceByState,
selectHistoricFiatRates,
} from '@suite-common/wallet-core';
import { isDeviceRemembered } from '@suite-common/suite-utils';
import { messageSystemActions } from '@suite-common/message-system';
Expand Down Expand Up @@ -74,7 +75,10 @@ const storageMiddleware = (api: MiddlewareAPI<Dispatch, AppState>) => {
}

if (transactionsActions.resetTransaction.match(action)) {
storageActions.removeAccountTransactions(action.payload.account);
const { account } = action.payload;

storageActions.removeAccountTransactions(account);
storageActions.removeAccountHistoricRates(account.key);
}

if (
Expand All @@ -85,10 +89,17 @@ const storageMiddleware = (api: MiddlewareAPI<Dispatch, AppState>) => {
) {
const { account } = action.payload;
const device = findAccountDevice(account, selectDevices(api.getState()));
const historicRates = selectHistoricFiatRates(api.getState());
// update only transactions for remembered device
if (isDeviceRemembered(device)) {
storageActions.removeAccountHistoricRates(account.key);
storageActions.removeAccountTransactions(account);
api.dispatch(storageActions.saveAccountTransactions(account));
if (historicRates) {
api.dispatch(
storageActions.saveAccountHistoricRates(account.key, historicRates),
);
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion packages/suite/src/storage/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DBSchema } from 'idb';
import { FieldValues } from 'react-hook-form';

import type { SuiteState } from 'src/reducers/suite/suiteReducer';
import type { FormState } from '@suite-common/wallet-types';
import type { FormState, RatesByTimestamps } from '@suite-common/wallet-types';
import type { AcquiredDevice } from 'src/types/suite';
import type { MetadataState } from 'src/types/suite/metadata';
import type { Trade } from 'src/types/wallet/coinmarketCommonTypes';
Expand Down Expand Up @@ -45,6 +45,10 @@ export interface SuiteDBSchema extends DBSchema {
evmSettings: SuiteState['evmSettings'];
};
};
historicRates: {
key: string;
value: RatesByTimestamps;
};
walletSettings: {
key: string;
value: WalletSettings;
Expand Down
2 changes: 1 addition & 1 deletion packages/suite/src/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { migrate } from './migrations';

import type { SuiteDBSchema } from './definitions';

const VERSION = 44; // don't forget to add migration and CHANGELOG when changing versions!
const VERSION = 45; // don't forget to add migration and CHANGELOG when changing versions!

/**
* If the object stores don't already exist then creates them.
Expand Down
3 changes: 3 additions & 0 deletions packages/suite/src/storage/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,9 @@ export const migrate: OnUpgradeFunc<SuiteDBSchema> = async (
}

if (oldVersion < 45) {
// object store for settings
db.createObjectStore('historicRates');

await updateAll(transaction, 'txs', tx => {
// @ts-expect-error
delete tx.tx.rates;
Expand Down
10 changes: 9 additions & 1 deletion packages/suite/src/support/extraDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { saveAs } from 'file-saver';
import { PayloadAction } from '@reduxjs/toolkit';

import { resolveStaticPath } from '@suite-common/suite-utils';
import { getAccountKey } from '@suite-common/wallet-utils';
import { getAccountKey, buildHistoricRatesFromStorage } from '@suite-common/wallet-utils';
import {
DeviceRootState,
selectIsPendingTransportEvent,
Expand All @@ -11,6 +11,7 @@ import {
DiscoveryRootState,
selectDiscoveryByDeviceState,
deviceActions,
FiatRatesState,
} from '@suite-common/wallet-core';
import { NetworkSymbol } from '@suite-common/wallet-config';
import { ExtraDependencies } from '@suite-common/redux-utils';
Expand Down Expand Up @@ -116,6 +117,13 @@ export const extraDependencies: ExtraDependencies = {
state.transactions[k][item.order] = item.tx;
});
},
storageLoadHistoricRates: (state: FiatRatesState, { payload }: StorageLoadAction) => {
if (payload.historicRates) {
const fiatRates = payload.historicRates.map(rate => rate.value);
const historicRates = buildHistoricRatesFromStorage(fiatRates);
state.historic = historicRates;
}
},
storageLoadAccounts: (_, { payload }: StorageLoadAction) =>
payload.accounts.map(acc =>
acc.backendType === 'coinjoin' ? fixLoadedCoinjoinAccount(acc) : acc,
Expand Down
2 changes: 2 additions & 0 deletions packages/suite/src/support/suite/preloadStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const preloadStore = async () => {
const discovery = await db.getItemsExtended('discovery');
const walletSettings = await db.getItemByPK('walletSettings', 'wallet');
const coinmarketTrades = await db.getItemsExtended('coinmarketTrades');
const historicRates = await db.getItemsWithKeys('historicRates');
const graph = await db.getItemsExtended('graph');
const analytics = await db.getItemByPK('analytics', 'suite');
const metadata = await db.getItemByPK('metadata', 'state');
Expand All @@ -52,6 +53,7 @@ export const preloadStore = async () => {
txs,
graph,
coinmarketTrades,
historicRates,
sendFormDrafts,
formDrafts,
analytics,
Expand Down
1 change: 1 addition & 0 deletions suite-common/redux-utils/src/extraDependenciesType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export type ExtraDependencies = {
storageLoadBlockchain: StorageLoadReducer;
storageLoadAccounts: StorageLoadReducer;
storageLoadTransactions: StorageLoadTransactionsReducer;
storageLoadHistoricRates: StorageLoadReducer;
storageLoadFirmware: StorageLoadReducer;
storageLoadDiscovery: StorageLoadReducer;
addButtonRequestFirmware: AddButtonRequestReducer;
Expand Down
1 change: 1 addition & 0 deletions suite-common/test-utils/src/extraDependenciesMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const extraDependenciesMock: ExtraDependencies = {
storageLoadBlockchain: mockReducer('storageLoadBlockchain'),
storageLoadAccounts: mockReducer('storageLoadAccounts'),
storageLoadTransactions: mockReducer('storageLoadTransactions'),
storageLoadHistoricRates: mockReducer('storageLoadHistoricRates'),
storageLoadFirmware: mockReducer('storageLoadFirmware'),
storageLoadDiscovery: mockReducer('storageLoadDiscovery'),
addButtonRequestFirmware: mockReducer('addButtonRequestFirmware'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const fiatRatesInitialState: FiatRatesState = {

export const prepareFiatRatesReducer = createReducerWithExtraDeps(
fiatRatesInitialState,
builder => {
(builder, extra) => {
builder
.addCase(updateFiatRatesThunk.pending, (state, action) => {
const { ticker, localCurrency, rateType } = action.meta.arg;
Expand Down
7 changes: 5 additions & 2 deletions suite-common/wallet-utils/src/transactionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const sumTransactions = (transactions: WalletAccountTransaction[]) => {
}

// count in only if Inputs/Outputs includes my account (EVM does not need to)
if (tx.targets.length && tx.type === 'sent') {
if (tx.type === 'sent') {
totalAmount = totalAmount.minus(amount);
}

Expand Down Expand Up @@ -200,7 +200,10 @@ export const sumTransactionsFiat = (
) => {
let totalAmount = new BigNumber(0);
transactions.forEach(tx => {
const amount = formatNetworkAmount(tx.amount, tx.symbol);
const isWithToken = tx.tokens[0]?.contract;
const amount = isWithToken
? formatAmount(tx.tokens[0]?.amount, tx.tokens[0]?.decimals)
: formatNetworkAmount(tx.amount, tx.symbol);
const fee = formatNetworkAmount(tx.fee, tx.symbol);

const fiatRateKey = getFiatRateKey(tx.symbol, fiatCurrency);
Expand Down

0 comments on commit 9e0bee6

Please sign in to comment.