1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-28 11:18:16 +00:00
trezor-wallet/src/js/services/LocalStorageService.js

147 lines
4.8 KiB
JavaScript
Raw Normal View History

2018-02-20 09:30:36 +00:00
/* @flow */
'use strict';
import * as LocalStorageActions from '../actions/LocalStorageActions';
2018-05-17 14:03:11 +00:00
import * as WalletActions from '../actions/WalletActions';
2018-02-20 09:30:36 +00:00
import { DEVICE } from 'trezor-connect';
import * as CONNECT from '../actions/constants/TrezorConnect';
2018-04-11 10:13:38 +00:00
import * as MODAL from '../actions/constants/modal';
import * as TOKEN from '../actions/constants/token';
import * as ACCOUNT from '../actions/constants/account';
2018-04-11 10:13:38 +00:00
import * as DISCOVERY from '../actions/constants/discovery';
import * as SEND from '../actions/constants/send';
import * as WEB3 from '../actions/constants/web3';
2018-04-23 10:20:15 +00:00
import * as PENDING from '../actions/constants/pendingTx';
2018-04-16 21:19:50 +00:00
import { LOCATION_CHANGE } from 'react-router-redux';
import { findAccountTokens } from '../reducers/TokensReducer';
2018-04-16 21:19:50 +00:00
import type {
Middleware,
MiddlewareAPI,
MiddlewareDispatch,
State,
Dispatch,
Action,
AsyncAction,
GetState
} from '~/flowtype';
2018-04-16 21:19:50 +00:00
import type { TrezorDevice } from '~/flowtype';
2018-04-16 21:19:50 +00:00
import type { Account } from '../reducers/AccountsReducer';
import type { Token } from '../reducers/TokensReducer';
import type { PendingTx } from '../reducers/PendingTxReducer';
import type { Discovery } from '../reducers/DiscoveryReducer';
2018-02-20 09:30:36 +00:00
// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js
// or
// https://www.npmjs.com/package/redux-react-session
2018-04-16 21:19:50 +00:00
const findAccounts = (devices: Array<TrezorDevice>, accounts: Array<Account>): Array<Account> => {
2018-02-20 09:30:36 +00:00
return devices.reduce((arr, dev) => {
return arr.concat(accounts.filter(a => a.deviceState === dev.state));
2018-02-20 09:30:36 +00:00
}, []);
}
2018-04-16 21:19:50 +00:00
const findTokens = (accounts: Array<Account>, tokens: Array<Token>): Array<Token> => {
2018-02-20 09:30:36 +00:00
return accounts.reduce((arr, account) => {
return arr.concat(findAccountTokens(tokens, account));
2018-02-20 09:30:36 +00:00
}, []);
}
2018-04-16 21:19:50 +00:00
const findDiscovery = (devices: Array<TrezorDevice>, discovery: Array<Discovery>): Array<Discovery> => {
2018-02-20 09:30:36 +00:00
return devices.reduce((arr, dev) => {
return arr.concat(discovery.filter(a => a.deviceState === dev.state && a.publicKey.length > 0));
2018-02-20 09:30:36 +00:00
}, []);
}
2018-04-16 21:19:50 +00:00
const findPendingTxs = (accounts: Array<Account>, pending: Array<PendingTx>): Array<PendingTx> => {
2018-03-08 16:10:53 +00:00
return accounts.reduce((arr, account) => {
return arr.concat(pending.filter(a => a.address === account.address));
}, []);
}
2018-04-16 21:19:50 +00:00
const save = (dispatch: Dispatch, getState: GetState): void => {
const devices: Array<TrezorDevice> = getState().connect.devices.filter(d => d.features && d.remember === true);
const accounts: Array<Account> = findAccounts(devices, getState().accounts);
const tokens: Array<Token> = findTokens(accounts, getState().tokens);
const pending: Array<PendingTx> = findPendingTxs(accounts, getState().pending);
const discovery: Array<Discovery> = findDiscovery(devices, getState().discovery);
2018-02-20 09:30:36 +00:00
// save devices
dispatch( LocalStorageActions.save('devices', JSON.stringify(devices) ) );
// save already preloaded accounts
dispatch( LocalStorageActions.save('accounts', JSON.stringify(accounts) ) );
// save discovery state
dispatch( LocalStorageActions.save('discovery', JSON.stringify(discovery) ) );
// tokens
dispatch( LocalStorageActions.save('tokens', JSON.stringify( tokens ) ) );
2018-03-08 16:10:53 +00:00
// pending transactions
dispatch( LocalStorageActions.save('pending', JSON.stringify( pending ) ) );
2018-02-20 09:30:36 +00:00
}
2018-04-16 21:19:50 +00:00
const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => {
2018-02-20 09:30:36 +00:00
2018-05-18 17:46:35 +00:00
// Application live cycle starts here
2018-02-20 09:30:36 +00:00
if (action.type === LOCATION_CHANGE) {
2018-04-16 21:19:50 +00:00
const { location } = api.getState().router;
2018-02-20 09:30:36 +00:00
if (!location) {
2018-05-17 14:03:11 +00:00
api.dispatch( WalletActions.init() );
2018-02-20 09:30:36 +00:00
// load data from config.json and local storage
2018-04-16 21:19:50 +00:00
api.dispatch( LocalStorageActions.loadData() );
2018-02-20 09:30:36 +00:00
}
}
next(action);
switch (action.type) {
// first time saving
case CONNECT.REMEMBER :
2018-04-16 21:19:50 +00:00
save(api.dispatch, api.getState);
2018-02-20 09:30:36 +00:00
break;
case TOKEN.ADD :
2018-03-08 16:10:53 +00:00
case TOKEN.REMOVE :
2018-02-20 09:30:36 +00:00
case TOKEN.SET_BALANCE :
2018-04-16 21:19:50 +00:00
save(api.dispatch, api.getState);
2018-02-20 09:30:36 +00:00
break;
case ACCOUNT.CREATE :
case ACCOUNT.SET_BALANCE :
case ACCOUNT.SET_NONCE :
2018-04-16 21:19:50 +00:00
save(api.dispatch, api.getState);
2018-02-20 09:30:36 +00:00
break;
case DISCOVERY.START :
case DISCOVERY.STOP :
case DISCOVERY.COMPLETE :
2018-04-16 21:19:50 +00:00
save(api.dispatch, api.getState);
2018-02-20 09:30:36 +00:00
break;
case CONNECT.FORGET :
case CONNECT.FORGET_SINGLE :
case DEVICE.CHANGED :
case DEVICE.DISCONNECT :
case CONNECT.AUTH_DEVICE :
case CONNECT.SELECT_DEVICE :
2018-04-16 21:19:50 +00:00
save(api.dispatch, api.getState);
2018-02-20 09:30:36 +00:00
break;
2018-03-08 16:10:53 +00:00
case SEND.TX_COMPLETE :
2018-04-23 10:20:15 +00:00
case PENDING.TX_RESOLVED :
2018-04-16 21:19:50 +00:00
save(api.dispatch, api.getState);
2018-03-08 16:10:53 +00:00
break;
2018-02-20 09:30:36 +00:00
}
2018-04-16 21:19:50 +00:00
return action;
2018-02-20 09:30:36 +00:00
};
export default LocalStorageService;