From a8bae8bdb1b8d3b342dc080b34aa32f5294db784 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Wed, 17 Oct 2018 12:09:25 +0200 Subject: [PATCH] added beta-wallet disclaimer - Added BetaDiscialmer component used in Landing/RootView - refactoring LocalStorageActions (moved logic from LocalStorageService) --- src/actions/LocalStorageActions.js | 352 ++++++++++-------- src/actions/ModalActions.js | 2 - src/actions/RouterActions.js | 2 +- src/actions/WalletActions.js | 6 + src/actions/constants/wallet.js | 2 + src/reducers/WalletReducer.js | 14 +- src/services/LocalStorageService.js | 75 +--- .../components/BetaDisclaimer/index.js | 80 ++++ src/views/Landing/views/Root/index.js | 3 + 9 files changed, 321 insertions(+), 215 deletions(-) create mode 100644 src/views/Landing/components/BetaDisclaimer/index.js diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index ae1c04c2..49fbf0fa 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -7,11 +7,23 @@ import * as TOKEN from 'actions/constants/token'; import * as DISCOVERY from 'actions/constants/discovery'; import * as STORAGE from 'actions/constants/localStorage'; import * as PENDING from 'actions/constants/pendingTx'; +import * as WALLET from 'actions/constants/wallet'; import { httpRequest } from 'utils/networkUtils'; import * as buildUtils from 'utils/build'; +import { findAccountTokens } from 'reducers/TokensReducer'; +import type { Account } from 'reducers/AccountsReducer'; +import type { Token } from 'reducers/TokensReducer'; +import type { PendingTx } from 'reducers/PendingTxReducer'; +import type { Discovery } from 'reducers/DiscoveryReducer'; + + import type { - ThunkAction, AsyncAction, /* GetState, */ Dispatch, + TrezorDevice, + ThunkAction, + AsyncAction, + GetState, + Dispatch, } from 'flowtype'; import type { Config, Network, TokensCollection } from 'reducers/LocalStorageReducer'; @@ -31,7 +43,7 @@ export type StorageAction = { error: string, }; -export const get = (key: string): ?string => { +const get = (key: string): ?string => { try { return window.localStorage.getItem(key); } catch (error) { @@ -40,168 +52,212 @@ export const get = (key: string): ?string => { } }; -export function update(event: StorageEvent): AsyncAction { - return async (dispatch: Dispatch/* , getState: GetState */): Promise => { - if (!event.newValue) return; +const set = (key: string, value: string | boolean): void => { + try { + window.localStorage.setItem(key, value); + } catch (error) { + console.error(`Local Storage ERROR: ${error}`); + } +}; - if (event.key === 'devices') { - // check if device was added/ removed - // const newDevices: Array = JSON.parse(event.newValue); - // const myDevices: Array = getState().connect.devices.filter(d => d.features); +// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js +// or +// https://www.npmjs.com/package/redux-react-session - // if (newDevices.length !== myDevices.length) { - // const diff = myDevices.filter(d => newDevices.indexOf(d) < 0) - // console.warn("DEV LIST CHANGED!", newDevices.length, myDevices.length, diff) - // // check if difference is caused by local device which is not saved - // // or device which was saved in other tab - // } +const findAccounts = (devices: Array, accounts: Array): Array => devices.reduce((arr, dev) => arr.concat(accounts.filter(a => a.deviceState === dev.state)), []); - // const diff = oldDevices.filter(d => newDevices.indexOf()) - } +const findTokens = (accounts: Array, tokens: Array): Array => accounts.reduce((arr, account) => arr.concat(findAccountTokens(tokens, account)), []); - if (event.key === 'accounts') { - dispatch({ - type: ACCOUNT.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } +const findDiscovery = (devices: Array, discovery: Array): Array => devices.reduce((arr, dev) => arr.concat(discovery.filter(a => a.deviceState === dev.state && a.publicKey.length > 0)), []); - if (event.key === 'tokens') { - dispatch({ - type: TOKEN.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } +const findPendingTxs = (accounts: Array, pending: Array): Array => accounts.reduce((result, account) => result.concat(pending.filter(p => p.address === account.address && p.network === account.network)), []); - if (event.key === 'pending') { - dispatch({ - type: PENDING.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } +export const save = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { + const devices: Array = getState().devices.filter(d => d.features && d.remember === true); + const accounts: Array = findAccounts(devices, getState().accounts); + const tokens: Array = findTokens(accounts, getState().tokens); + const pending: Array = findPendingTxs(accounts, getState().pending); + const discovery: Array = findDiscovery(devices, getState().discovery); - if (event.key === 'discovery') { - dispatch({ - type: DISCOVERY.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } - }; -} + // save devices + set('devices', JSON.stringify(devices)); + + // save already preloaded accounts + set('accounts', JSON.stringify(accounts)); + + // save discovery state + set('discovery', JSON.stringify(discovery)); + + // tokens + set('tokens', JSON.stringify(tokens)); + + // pending transactions + set('pending', JSON.stringify(pending)); +}; + +export const update = (event: StorageEvent): ThunkAction => (dispatch: Dispatch): void => { + if (!event.newValue) return; + + if (event.key === 'devices') { + // check if device was added/ removed + // const newDevices: Array = JSON.parse(event.newValue); + // const myDevices: Array = getState().connect.devices.filter(d => d.features); + + // if (newDevices.length !== myDevices.length) { + // const diff = myDevices.filter(d => newDevices.indexOf(d) < 0) + // console.warn("DEV LIST CHANGED!", newDevices.length, myDevices.length, diff) + // // check if difference is caused by local device which is not saved + // // or device which was saved in other tab + // } + + // const diff = oldDevices.filter(d => newDevices.indexOf()) + } + + if (event.key === 'accounts') { + dispatch({ + type: ACCOUNT.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } + + if (event.key === 'tokens') { + dispatch({ + type: TOKEN.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } + + if (event.key === 'pending') { + dispatch({ + type: PENDING.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } + + if (event.key === 'discovery') { + dispatch({ + type: DISCOVERY.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } +}; const VERSION: string = '1'; -export function loadTokensFromJSON(): AsyncAction { - return async (dispatch: Dispatch): Promise => { - if (typeof window.localStorage === 'undefined') return; +const loadJSON = (): AsyncAction => async (dispatch: Dispatch): Promise => { + if (typeof window.localStorage === 'undefined') return; - try { - const config: Config = await httpRequest(AppConfigJSON, 'json'); + try { + const config: Config = await httpRequest(AppConfigJSON, 'json'); - if (!buildUtils.isDev()) { - const index = config.networks.findIndex(c => c.shortcut === 'trop'); - delete config.networks[index]; - } - - const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json'); - - window.addEventListener('storage', (event) => { - dispatch(update(event)); - }); - - // validate version - const version: ?string = get('version'); - if (version !== VERSION) { - window.localStorage.clear(); - dispatch(save('version', VERSION)); - } - - // load tokens - const tokens = await config.networks.reduce(async (promise: Promise, network: Network): Promise => { - const collection: TokensCollection = await promise; - const json = await httpRequest(network.tokens, 'json'); - collection[network.shortcut] = json; - return collection; - }, Promise.resolve({})); - - const devices: ?string = get('devices'); - if (devices) { - dispatch({ - type: CONNECT.DEVICE_FROM_STORAGE, - payload: JSON.parse(devices), - }); - } - - const accounts: ?string = get('accounts'); - if (accounts) { - dispatch({ - type: ACCOUNT.FROM_STORAGE, - payload: JSON.parse(accounts), - }); - } - - const userTokens: ?string = get('tokens'); - if (userTokens) { - dispatch({ - type: TOKEN.FROM_STORAGE, - payload: JSON.parse(userTokens), - }); - } - - const pending: ?string = get('pending'); - if (pending) { - dispatch({ - type: PENDING.FROM_STORAGE, - payload: JSON.parse(pending), - }); - } - - const discovery: ?string = get('discovery'); - if (discovery) { - dispatch({ - type: DISCOVERY.FROM_STORAGE, - payload: JSON.parse(discovery), - }); - } - - dispatch({ - type: STORAGE.READY, - config, - tokens, - ERC20Abi, - }); - } catch (error) { - dispatch({ - type: STORAGE.ERROR, - error, - }); + if (!buildUtils.isDev()) { + const index = config.networks.findIndex(c => c.shortcut === 'trop'); + delete config.networks[index]; } - }; -} -export const loadData = (): ThunkAction => (dispatch: Dispatch): void => { - // check if local storage is available - // let available: boolean = true; - // if (typeof window.localStorage === 'undefined') { - // available = false; - // } else { - // try { - // window.localStorage.setItem('ethereum_wallet', true); - // } catch (error) { - // available = false; - // } - // } + const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json'); - dispatch(loadTokensFromJSON()); + window.addEventListener('storage', (event) => { + dispatch(update(event)); + }); + + // validate version + const version: ?string = get('version'); + if (version !== VERSION) { + try { + window.localStorage.clear(); + window.sessionStorage.clear(); + } catch (error) { + // empty + } + set('version', VERSION); + } + + // load tokens + const tokens = await config.networks.reduce(async (promise: Promise, network: Network): Promise => { + const collection: TokensCollection = await promise; + const json = await httpRequest(network.tokens, 'json'); + collection[network.shortcut] = json; + return collection; + }, Promise.resolve({})); + + dispatch({ + type: STORAGE.READY, + config, + tokens, + ERC20Abi, + }); + } catch (error) { + dispatch({ + type: STORAGE.ERROR, + error, + }); + } }; -export const save = (key: string, value: string): ThunkAction => (): void => { - if (typeof window.localStorage !== 'undefined') { - try { - window.localStorage.setItem(key, value); - } catch (error) { - // available = false; - console.error(`Local Storage ERROR: ${error}`); + +const loadStorageData = (): ThunkAction => (dispatch: Dispatch): void => { + const devices: ?string = get('devices'); + if (devices) { + dispatch({ + type: CONNECT.DEVICE_FROM_STORAGE, + payload: JSON.parse(devices), + }); + } + + const accounts: ?string = get('accounts'); + if (accounts) { + dispatch({ + type: ACCOUNT.FROM_STORAGE, + payload: JSON.parse(accounts), + }); + } + + const userTokens: ?string = get('tokens'); + if (userTokens) { + dispatch({ + type: TOKEN.FROM_STORAGE, + payload: JSON.parse(userTokens), + }); + } + + const pending: ?string = get('pending'); + if (pending) { + dispatch({ + type: PENDING.FROM_STORAGE, + payload: JSON.parse(pending), + }); + } + + const discovery: ?string = get('discovery'); + if (discovery) { + dispatch({ + type: DISCOVERY.FROM_STORAGE, + payload: JSON.parse(discovery), + }); + } + + if (buildUtils.isDev() || buildUtils.isBeta()) { + const betaModal = get('/betaModalPrivacy'); + if (!betaModal) { + dispatch({ + type: WALLET.SHOW_BETA_DISCLAIMER, + show: true, + }); } } -}; \ No newline at end of file +}; + +export const loadData = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { + dispatch(loadStorageData()); + + // stop loading resources and wait for user action + if (!getState().wallet.showBetaDisclaimer) { + dispatch(loadJSON()); + } +}; + +export const hideBetaDisclaimer = (): ThunkAction => (dispatch: Dispatch): void => { + set('/betaModalPrivacy', true); + dispatch(loadJSON()); +}; diff --git a/src/actions/ModalActions.js b/src/actions/ModalActions.js index a9def9fe..c0856481 100644 --- a/src/actions/ModalActions.js +++ b/src/actions/ModalActions.js @@ -119,7 +119,6 @@ export const onWalletTypeRequest = (device: TrezorDevice, hidden: boolean, state }; export const gotoExternalWallet = (id: string, url: string): ThunkAction => (dispatch: Dispatch): void => { - console.warn('OPEN', id, url); dispatch({ type: MODAL.OPEN_EXTERNAL_WALLET, id, @@ -127,7 +126,6 @@ export const gotoExternalWallet = (id: string, url: string): ThunkAction => (dis }); }; - export default { onPinSubmit, onPassphraseSubmit, diff --git a/src/actions/RouterActions.js b/src/actions/RouterActions.js index 4e744df7..d4c5842b 100644 --- a/src/actions/RouterActions.js +++ b/src/actions/RouterActions.js @@ -153,7 +153,7 @@ export const getValidUrl = (action: RouterAction): PayloadAction => (dis const shouldBeLandingPage = getState().devices.length < 1 || !getState().wallet.ready || getState().connect.error !== null; const landingPageUrl = dispatch(isLandingPageUrl(requestedUrl)); if (shouldBeLandingPage) { - const landingPageRoute = dispatch(isLandingPageUrl(requestedUrl, true)); + const landingPageRoute = dispatch(isLandingPageUrl(requestedUrl, getState().wallet.ready)); return !landingPageRoute ? '/' : requestedUrl; } diff --git a/src/actions/WalletActions.js b/src/actions/WalletActions.js index 0cd065d3..f0d72a1b 100644 --- a/src/actions/WalletActions.js +++ b/src/actions/WalletActions.js @@ -38,6 +38,8 @@ export type WalletAction = { } | { type: typeof WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA, devices: Array +} | { + type: typeof WALLET.SHOW_BETA_DISCLAIMER | typeof WALLET.HIDE_BETA_DISCLAIMER, } export const init = (): ThunkAction => (dispatch: Dispatch): void => { @@ -51,6 +53,10 @@ export const init = (): ThunkAction => (dispatch: Dispatch): void => { window.addEventListener('offline', updateOnlineStatus); }; +export const hideBetaDisclaimer = (): WalletAction => ({ + type: WALLET.HIDE_BETA_DISCLAIMER, +}); + export const toggleDeviceDropdown = (opened: boolean): WalletAction => ({ type: WALLET.TOGGLE_DEVICE_DROPDOWN, opened, diff --git a/src/actions/constants/wallet.js b/src/actions/constants/wallet.js index 84cb4011..6f449a7a 100644 --- a/src/actions/constants/wallet.js +++ b/src/actions/constants/wallet.js @@ -6,5 +6,7 @@ export const ONLINE_STATUS: 'wallet__online_status' = 'wallet__online_status'; export const SET_SELECTED_DEVICE: 'wallet__set_selected_device' = 'wallet__set_selected_device'; export const UPDATE_SELECTED_DEVICE: 'wallet__update_selected_device' = 'wallet__update_selected_device'; +export const SHOW_BETA_DISCLAIMER: 'wallet__show_beta_disclaimer' = 'wallet__show_beta_disclaimer'; +export const HIDE_BETA_DISCLAIMER: 'wallet__hide_beta_disclaimer' = 'wallet__hide_beta_disclaimer'; export const CLEAR_UNAVAILABLE_DEVICE_DATA: 'wallet__clear_unavailable_device_data' = 'wallet__clear_unavailable_device_data'; \ No newline at end of file diff --git a/src/reducers/WalletReducer.js b/src/reducers/WalletReducer.js index 4e13807f..37fd38fd 100644 --- a/src/reducers/WalletReducer.js +++ b/src/reducers/WalletReducer.js @@ -7,13 +7,13 @@ import * as MODAL from 'actions/constants/modal'; import * as WALLET from 'actions/constants/wallet'; import * as CONNECT from 'actions/constants/TrezorConnect'; - import type { Action, RouterLocationState, TrezorDevice } from 'flowtype'; type State = { ready: boolean; online: boolean; dropdownOpened: boolean; + showBetaDisclaimer: boolean; initialParams: ?RouterLocationState; initialPathname: ?string; disconnectRequest: ?TrezorDevice; @@ -24,6 +24,7 @@ const initialState: State = { ready: false, online: navigator.onLine, dropdownOpened: false, + showBetaDisclaimer: false, initialParams: null, initialPathname: null, disconnectRequest: null, @@ -86,6 +87,17 @@ export default function wallet(state: State = initialState, action: Action): Sta selectedDevice: action.device, }; + case WALLET.SHOW_BETA_DISCLAIMER: + return { + ...state, + showBetaDisclaimer: true, + }; + case WALLET.HIDE_BETA_DISCLAIMER: + return { + ...state, + showBetaDisclaimer: false, + }; + default: return state; } diff --git a/src/services/LocalStorageService.js b/src/services/LocalStorageService.js index b98fbf62..ffd984e0 100644 --- a/src/services/LocalStorageService.js +++ b/src/services/LocalStorageService.js @@ -1,7 +1,6 @@ /* @flow */ import { DEVICE } from 'trezor-connect'; import * as LocalStorageActions from 'actions/LocalStorageActions'; -// import * as WalletActions from 'actions/WalletActions'; import * as CONNECT from 'actions/constants/TrezorConnect'; import * as TOKEN from 'actions/constants/token'; @@ -9,95 +8,45 @@ import * as ACCOUNT from 'actions/constants/account'; import * as DISCOVERY from 'actions/constants/discovery'; import * as SEND from 'actions/constants/send'; import * as PENDING from 'actions/constants/pendingTx'; -import { findAccountTokens } from 'reducers/TokensReducer'; +import * as WALLET from 'actions/constants/wallet'; + import type { Middleware, MiddlewareAPI, MiddlewareDispatch, - Dispatch, Action, - GetState, - TrezorDevice, } from 'flowtype'; -import type { Account } from 'reducers/AccountsReducer'; -import type { Token } from 'reducers/TokensReducer'; -import type { PendingTx } from 'reducers/PendingTxReducer'; -import type { Discovery } from 'reducers/DiscoveryReducer'; - - -// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js -// or -// https://www.npmjs.com/package/redux-react-session - -const findAccounts = (devices: Array, accounts: Array): Array => devices.reduce((arr, dev) => arr.concat(accounts.filter(a => a.deviceState === dev.state)), []); - -const findTokens = (accounts: Array, tokens: Array): Array => accounts.reduce((arr, account) => arr.concat(findAccountTokens(tokens, account)), []); - -const findDiscovery = (devices: Array, discovery: Array): Array => devices.reduce((arr, dev) => arr.concat(discovery.filter(a => a.deviceState === dev.state && a.publicKey.length > 0)), []); - -const findPendingTxs = (accounts: Array, pending: Array): Array => accounts.reduce((result, account) => result.concat(pending.filter(p => p.address === account.address && p.network === account.network)), []); - -const save = (dispatch: Dispatch, getState: GetState): void => { - const devices: Array = getState().devices.filter(d => d.features && d.remember === true); - const accounts: Array = findAccounts(devices, getState().accounts); - const tokens: Array = findTokens(accounts, getState().tokens); - const pending: Array = findPendingTxs(accounts, getState().pending); - const discovery: Array = findDiscovery(devices, getState().discovery); - - // 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))); - - // pending transactions - dispatch(LocalStorageActions.save('pending', JSON.stringify(pending))); -}; - - const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => { - // Application live cycle starts here - // if (action.type === LOCATION_CHANGE) { - // const { location } = api.getState().router; - // if (!location) { - // api.dispatch( WalletActions.init() ); - // // load data from config.json and local storage - // api.dispatch( LocalStorageActions.loadData() ); - // } - // } - + // pass action next(action); switch (action.type) { + case WALLET.HIDE_BETA_DISCLAIMER: + api.dispatch(LocalStorageActions.hideBetaDisclaimer()); + break; // first time saving case CONNECT.REMEMBER: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case TOKEN.ADD: case TOKEN.REMOVE: case TOKEN.SET_BALANCE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case ACCOUNT.CREATE: case ACCOUNT.SET_BALANCE: case ACCOUNT.SET_NONCE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case DISCOVERY.START: case DISCOVERY.STOP: case DISCOVERY.COMPLETE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case CONNECT.FORGET: @@ -107,13 +56,13 @@ const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: Middlewar case DEVICE.CHANGED: case DEVICE.DISCONNECT: case CONNECT.AUTH_DEVICE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case SEND.TX_COMPLETE: case PENDING.TX_RESOLVED: case PENDING.TX_REJECTED: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; default: diff --git a/src/views/Landing/components/BetaDisclaimer/index.js b/src/views/Landing/components/BetaDisclaimer/index.js new file mode 100644 index 00000000..64177997 --- /dev/null +++ b/src/views/Landing/components/BetaDisclaimer/index.js @@ -0,0 +1,80 @@ +/* @flow */ + +import React from 'react'; +import styled from 'styled-components'; +import { connect } from 'react-redux'; +import { bindActionCreators } from 'redux'; + +import colors from 'config/colors'; +import icons from 'config/icons'; + +import Icon from 'components/Icon'; +import Button from 'components/Button'; +import P from 'components/Paragraph'; +import { H2 } from 'components/Heading'; +import * as WalletActions from 'actions/WalletActions'; + +const Wrapper = styled.div` + width: 100%; + height: 100%; + top: 0px; + left: 0px; + background: rgba(0, 0, 0, 0.35); + display: flex; + flex-direction: column; + align-items: center; + overflow: auto; + padding: 20px; +`; + +const ModalWindow = styled.div` + margin: auto; + position: relative; + border-radius: 4px; + background-color: ${colors.WHITE}; + text-align: center; + width: 100%; + max-width: 620px; + padding: 24px 48px; +`; + +const StyledP = styled(P)` + padding: 10px 0px; + font-size: 14px; +`; + +const StyledButton = styled(Button)` + margin: 10px 0px; + width: 100%; +`; + +const StyledIcon = styled(Icon)` + position: relative; + top: -1px; +`; + +const BetaDisclaimer = (props: { close: () => void }) => ( + + +

You are opening Trezor Beta Wallet

+ Trezor Beta Wallet is a public feature-testing version of the Trezor Wallet, offering the newest features before they are available to the general public. + In contrast, Trezor Wallet is feature-conservative, making sure that its functionality is maximally reliable and dependable for the general public. + + + Please note that the Trezor Beta Wallet might be collecting anonymized usage data, especially error logs, for development purposes. The Trezor Wallet does not log any data. + + OK, I understand +
+
+); + +export default connect( + null, + (dispatch: Dispatch) => ({ + close: bindActionCreators(WalletActions.hideBetaDisclaimer, dispatch), + }), +)(BetaDisclaimer); \ No newline at end of file diff --git a/src/views/Landing/views/Root/index.js b/src/views/Landing/views/Root/index.js index f6c70272..bb55d146 100644 --- a/src/views/Landing/views/Root/index.js +++ b/src/views/Landing/views/Root/index.js @@ -4,6 +4,7 @@ import React from 'react'; import { isWebUSB } from 'utils/device'; import LandingWrapper from 'views/Landing/components/LandingWrapper'; +import BetaDisclaimer from 'views/Landing/components/BetaDisclaimer'; import BrowserNotSupported from 'views/Landing/components/BrowserNotSupported'; import ConnectDevice from 'views/Landing/components/ConnectDevice'; import InstallBridge from 'views/Landing/views/InstallBridge/Container'; @@ -16,6 +17,8 @@ const Root = (props: Props) => { const localStorageError = props.localStorage.error; const connectError = props.connect.error; + if (props.wallet.showBetaDisclaimer) return ; + const error = !initialized ? (localStorageError || connectError) : null; const shouldShowUnsupportedBrowser = browserState.supported === false; const shouldShowInstallBridge = initialized && connectError;