2018-05-22 17:42:03 +00:00
|
|
|
/* @flow */
|
2018-05-28 17:42:03 +00:00
|
|
|
import { DEVICE } from 'trezor-connect';
|
2018-12-18 13:33:01 +00:00
|
|
|
import { LOCATION_CHANGE } from 'connected-react-router';
|
2018-08-14 13:11:52 +00:00
|
|
|
import * as WALLET from 'actions/constants/wallet';
|
2018-09-20 18:26:58 +00:00
|
|
|
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';
|
2018-09-20 18:26:58 +00:00
|
|
|
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';
|
2018-10-04 08:48:23 +00:00
|
|
|
import * as DiscoveryActions from 'actions/DiscoveryActions';
|
2018-10-08 13:52:24 +00:00
|
|
|
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
|
2019-04-12 14:22:57 +00:00
|
|
|
// exclude landing page url
|
|
|
|
const { pathname } = action.payload.location;
|
|
|
|
const isValidPath = !api.dispatch(RouterActions.isLandingPageUrl(pathname, true));
|
2019-04-12 15:13:42 +00:00
|
|
|
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);
|
|
|
|
|
2018-09-20 18:26:58 +00:00
|
|
|
switch (action.type) {
|
2019-04-12 15:13:42 +00:00
|
|
|
case WALLET.SET_FIRST_LOCATION_CHANGE:
|
|
|
|
api.dispatch(LocalStorageActions.loadData());
|
2018-09-20 18:26:58 +00:00
|
|
|
break;
|
2018-09-21 12:01:41 +00:00
|
|
|
case WALLET.SET_SELECTED_DEVICE:
|
2018-10-05 13:47:37 +00:00
|
|
|
// try to authorize device
|
|
|
|
// api.dispatch(TrezorConnectActions.authorizeDevice());
|
|
|
|
api.dispatch(TrezorConnectActions.requestWalletType());
|
2018-09-21 12:01:41 +00:00
|
|
|
break;
|
2018-09-20 18:26:58 +00:00
|
|
|
case DEVICE.CONNECT:
|
|
|
|
api.dispatch(WalletActions.clearUnavailableDevicesData(prevState, action.device));
|
|
|
|
break;
|
|
|
|
default: {
|
|
|
|
break;
|
|
|
|
}
|
2018-05-28 17:42:03 +00:00
|
|
|
}
|
|
|
|
|
2018-09-20 16:26:45 +00:00
|
|
|
// update common values ONLY if application is ready
|
2018-09-20 18:26:58 +00:00
|
|
|
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));
|
2019-04-12 14:22:57 +00:00
|
|
|
|
2018-09-20 18:26:58 +00:00
|
|
|
// 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)
|
2018-09-20 18:26:58 +00:00
|
|
|
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
|
2018-09-20 18:26:58 +00:00
|
|
|
if (prevLocation.state.network !== currentLocation.state.network) {
|
|
|
|
api.dispatch({
|
2018-10-15 13:44:10 +00:00
|
|
|
type: CONNECT.NETWORK_CHANGED,
|
2018-09-20 18:26:58 +00:00
|
|
|
payload: {
|
|
|
|
network: currentLocation.state.network,
|
|
|
|
},
|
|
|
|
});
|
2018-10-04 08:48:23 +00:00
|
|
|
|
|
|
|
// 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());
|
2018-09-20 18:26:58 +00:00
|
|
|
}
|
2018-05-22 20:07:25 +00:00
|
|
|
|
2018-09-20 18:26:58 +00:00
|
|
|
// 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
|
|
|
|
) {
|
2018-09-20 18:26:58 +00:00
|
|
|
api.dispatch(SelectedAccountActions.dispose());
|
2018-05-22 17:42:03 +00:00
|
|
|
}
|
2018-09-20 18:26:58 +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());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-04 08:48:23 +00:00
|
|
|
// 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-10-01 09:59:31 +00:00
|
|
|
}
|
2018-09-20 18:26:58 +00:00
|
|
|
|
2018-05-22 17:42:03 +00:00
|
|
|
return action;
|
|
|
|
};
|
|
|
|
|
2019-03-04 12:33:02 +00:00
|
|
|
export default WalletService;
|