1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-30 20:28:09 +00:00
trezor-wallet/src/services/WalletService.js

139 lines
5.3 KiB
JavaScript
Raw Normal View History

2018-05-22 17:42:03 +00:00
/* @flow */
import { DEVICE } from 'trezor-connect';
import { LOCATION_CHANGE } from 'connected-react-router';
2018-08-14 13:11:52 +00:00
import * as WALLET from 'actions/constants/wallet';
import * as CONNECT from 'actions/constants/TrezorConnect';
2018-05-22 17:42:03 +00:00
2018-08-14 13:11:52 +00:00
import * as WalletActions from 'actions/WalletActions';
import * as NotificationActions from 'actions/NotificationActions';
2018-08-14 13:11:52 +00:00
import * as LocalStorageActions from 'actions/LocalStorageActions';
import * as TrezorConnectActions from 'actions/TrezorConnectActions';
import * as SelectedAccountActions from 'actions/SelectedAccountActions';
2018-11-29 20:06:35 +00:00
import * as SendFormActions from 'actions/SendFormActions';
import * as DiscoveryActions from 'actions/DiscoveryActions';
import * as RouterActions from 'actions/RouterActions';
2018-05-22 17:42:03 +00:00
2019-03-04 12:33:02 +00:00
import type { Middleware, MiddlewareAPI, MiddlewareDispatch, Action } from 'flowtype';
2018-05-22 17:42:03 +00:00
/**
2018-07-30 10:52:13 +00:00
* Middleware
2018-05-22 17:42:03 +00:00
*/
2019-03-04 12:33:02 +00:00
const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => async (
action: Action
): Promise<Action> => {
2018-05-22 17:42:03 +00:00
const prevState = api.getState();
2018-09-20 21:05:48 +00:00
// Application live cycle starts HERE!
// when first LOCATION_CHANGE is called router does not have "location" set yet
2018-12-18 16:05:06 +00:00
if (action.type === LOCATION_CHANGE && prevState.wallet.firstLocationChange) {
2018-09-20 21:05:48 +00:00
// initialize wallet
api.dispatch(WalletActions.init());
// set initial url
// TODO: validate if initial url is potentially correct
// exclude landing page url
const { pathname } = action.payload.location;
const isValidPath = !api.dispatch(RouterActions.isLandingPageUrl(pathname, true));
if (isValidPath) {
api.dispatch({
type: WALLET.SET_INITIAL_URL,
pathname,
state: {},
});
}
2018-09-20 21:05:48 +00:00
// pass action and break process
return next(action);
2018-05-22 17:42:03 +00:00
}
2018-07-30 10:52:13 +00:00
// pass action
2018-05-22 17:42:03 +00:00
next(action);
switch (action.type) {
case WALLET.SET_FIRST_LOCATION_CHANGE:
api.dispatch(LocalStorageActions.loadData());
break;
2018-09-21 12:01:41 +00:00
case WALLET.SET_SELECTED_DEVICE:
// try to authorize device
// api.dispatch(TrezorConnectActions.authorizeDevice());
api.dispatch(TrezorConnectActions.requestWalletType());
2018-09-21 12:01:41 +00:00
break;
case DEVICE.CONNECT:
api.dispatch(WalletActions.clearUnavailableDevicesData(prevState, action.device));
break;
default: {
break;
}
}
// update common values ONLY if application is ready
if (!api.getState().wallet.ready) return action;
2018-05-22 17:42:03 +00:00
2019-04-15 09:35:14 +00:00
// check for "selectedDevice" change before any action
const selectedDeviceDidChange = await api.dispatch(WalletActions.observe(prevState, action));
// double verification needed
2018-09-20 21:05:48 +00:00
// Corner case: LOCATION_CHANGE was called but pathname didn't changed (redirection from RouterService)
const prevLocation = prevState.router.location;
const currentLocation = api.getState().router.location;
2018-09-20 21:05:48 +00:00
if (action.type === LOCATION_CHANGE && prevLocation.pathname !== currentLocation.pathname) {
2018-10-15 13:44:10 +00:00
// watch for network change
if (prevLocation.state.network !== currentLocation.state.network) {
api.dispatch({
2018-10-15 13:44:10 +00:00
type: CONNECT.NETWORK_CHANGED,
payload: {
network: currentLocation.state.network,
},
});
// try to stop currently running discovery on previous network
api.dispatch(DiscoveryActions.stop());
// try to start new discovery on new network
api.dispatch(DiscoveryActions.restore());
}
// watch for account change
2019-03-04 12:33:02 +00:00
if (
prevLocation.state.network !== currentLocation.state.network ||
prevLocation.state.account !== currentLocation.state.account
) {
api.dispatch(SelectedAccountActions.dispose());
2018-05-22 17:42:03 +00:00
}
// clear notifications
api.dispatch(NotificationActions.clear(prevLocation.state, currentLocation.state));
2018-05-22 17:42:03 +00:00
}
2019-04-15 09:35:14 +00:00
// if "selectedDevice" didn't change observe common values in SelectedAccountReducer
if (!selectedDeviceDidChange) {
if (!(await api.dispatch(SelectedAccountActions.observe(prevState, action)))) {
// if "selectedAccount" didn't change observe send form props changes
api.dispatch(SendFormActions.observe(prevState, action));
}
} else {
// no changes in common values
if (action.type === CONNECT.RECEIVE_WALLET_TYPE) {
if (action.device.state) {
// redirect to root view (Dashboard) if device was authenticated before
api.dispatch(RouterActions.selectFirstAvailableDevice(true));
}
api.dispatch(TrezorConnectActions.authorizeDevice());
}
if (action.type === CONNECT.AUTH_DEVICE) {
// selected device did changed
// try to restore discovery after device authentication
api.dispatch(DiscoveryActions.restore());
}
}
// even if "selectedDevice" didn't change because it was updated on DEVICE.CHANGED before DEVICE.CONNECT action
// try to restore discovery
if (action.type === DEVICE.CONNECT) {
api.dispatch(DiscoveryActions.restore());
} else if (action.type === DEVICE.DISCONNECT) {
api.dispatch(DiscoveryActions.stop());
}
2018-05-22 17:42:03 +00:00
return action;
};
2019-03-04 12:33:02 +00:00
export default WalletService;