Disable more wallets conditionally + explain why (#924)
* Add more wallet disables, move all into selector. * Add reasons for disabled wallets. * Disable read only in lite send. * Fix view address showing insecure icon.
This commit is contained in:
parent
df52521c17
commit
2309d05c06
|
@ -32,8 +32,9 @@ import {
|
||||||
InsecureWalletWarning
|
InsecureWalletWarning
|
||||||
} from './components';
|
} from './components';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import DISABLES from './disables';
|
|
||||||
import { showNotification, TShowNotification } from 'actions/notifications';
|
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||||
|
import { getDisabledWallets } from 'selectors/wallet';
|
||||||
|
import { DisabledWallets } from './disables';
|
||||||
|
|
||||||
import LedgerIcon from 'assets/images/wallets/ledger.svg';
|
import LedgerIcon from 'assets/images/wallets/ledger.svg';
|
||||||
import MetamaskIcon from 'assets/images/wallets/metamask.svg';
|
import MetamaskIcon from 'assets/images/wallets/metamask.svg';
|
||||||
|
@ -48,12 +49,10 @@ import {
|
||||||
isWeb3NodeAvailable,
|
isWeb3NodeAvailable,
|
||||||
knowledgeBaseURL
|
knowledgeBaseURL
|
||||||
} from 'config';
|
} from 'config';
|
||||||
import { unSupportedWalletFormatsOnNetwork } from 'utils/network';
|
|
||||||
import { getNetworkConfig } from '../../selectors/config';
|
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
disabledWallets?: WalletName[];
|
disabledWallets?: DisabledWallets;
|
||||||
showGenerateLink?: boolean;
|
showGenerateLink?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +68,7 @@ interface DispatchProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
computedDisabledWallets: WalletName[];
|
computedDisabledWallets: DisabledWallets;
|
||||||
offline: boolean;
|
|
||||||
isWalletPending: AppState['wallet']['isWalletPending'];
|
isWalletPending: AppState['wallet']['isWalletPending'];
|
||||||
isPasswordPending: AppState['wallet']['isPasswordPending'];
|
isPasswordPending: AppState['wallet']['isPasswordPending'];
|
||||||
}
|
}
|
||||||
|
@ -282,6 +280,9 @@ export class WalletDecrypt extends Component<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
public buildWalletOptions() {
|
public buildWalletOptions() {
|
||||||
|
const { computedDisabledWallets } = this.props;
|
||||||
|
const { reasons } = computedDisabledWallets;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="WalletDecrypt-wallets">
|
<div className="WalletDecrypt-wallets">
|
||||||
<h2 className="WalletDecrypt-wallets-title">{translate('decrypt_Access')}</h2>
|
<h2 className="WalletDecrypt-wallets-title">{translate('decrypt_Access')}</h2>
|
||||||
|
@ -299,6 +300,7 @@ export class WalletDecrypt extends Component<Props, State> {
|
||||||
walletType={walletType}
|
walletType={walletType}
|
||||||
isSecure={true}
|
isSecure={true}
|
||||||
isDisabled={this.isWalletDisabled(walletType)}
|
isDisabled={this.isWalletDisabled(walletType)}
|
||||||
|
disableReason={reasons[walletType]}
|
||||||
onClick={this.handleWalletChoice}
|
onClick={this.handleWalletChoice}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -316,6 +318,7 @@ export class WalletDecrypt extends Component<Props, State> {
|
||||||
walletType={walletType}
|
walletType={walletType}
|
||||||
isSecure={false}
|
isSecure={false}
|
||||||
isDisabled={this.isWalletDisabled(walletType)}
|
isDisabled={this.isWalletDisabled(walletType)}
|
||||||
|
disableReason={reasons[walletType]}
|
||||||
onClick={this.handleWalletChoice}
|
onClick={this.handleWalletChoice}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -332,6 +335,7 @@ export class WalletDecrypt extends Component<Props, State> {
|
||||||
walletType={walletType}
|
walletType={walletType}
|
||||||
isReadOnly={true}
|
isReadOnly={true}
|
||||||
isDisabled={this.isWalletDisabled(walletType)}
|
isDisabled={this.isWalletDisabled(walletType)}
|
||||||
|
disableReason={reasons[walletType]}
|
||||||
onClick={this.handleWalletChoice}
|
onClick={this.handleWalletChoice}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -426,24 +430,26 @@ export class WalletDecrypt extends Component<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private isWalletDisabled = (walletKey: WalletName) => {
|
private isWalletDisabled = (walletKey: WalletName) => {
|
||||||
if (this.props.offline && DISABLES.ONLINE_ONLY.includes(walletKey)) {
|
return this.props.computedDisabledWallets.wallets.indexOf(walletKey) !== -1;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.props.computedDisabledWallets.indexOf(walletKey) !== -1;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state: AppState, ownProps: Props) {
|
function mapStateToProps(state: AppState, ownProps: Props) {
|
||||||
const { disabledWallets } = ownProps;
|
const { disabledWallets } = ownProps;
|
||||||
const network = getNetworkConfig(state);
|
let computedDisabledWallets = getDisabledWallets(state);
|
||||||
const networkDisabledFormats = unSupportedWalletFormatsOnNetwork(network);
|
|
||||||
const computedDisabledWallets = disabledWallets
|
if (disabledWallets) {
|
||||||
? disabledWallets.concat(networkDisabledFormats)
|
computedDisabledWallets = {
|
||||||
: networkDisabledFormats;
|
wallets: [...computedDisabledWallets.wallets, ...disabledWallets.wallets],
|
||||||
|
reasons: {
|
||||||
|
...computedDisabledWallets.reasons,
|
||||||
|
...disabledWallets.reasons
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
computedDisabledWallets,
|
computedDisabledWallets,
|
||||||
offline: state.config.offline,
|
|
||||||
isWalletPending: state.wallet.isWalletPending,
|
isWalletPending: state.wallet.isWalletPending,
|
||||||
isPasswordPending: state.wallet.isPasswordPending
|
isPasswordPending: state.wallet.isPasswordPending
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,16 +12,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes wallet-button-enter-disabled {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
30%,
|
|
||||||
100% {
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.WalletButton {
|
.WalletButton {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -70,10 +60,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-disabled {
|
&.is-disabled {
|
||||||
opacity: 0.3 !important;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
animation-name: wallet-button-enter, wallet-button-enter-disabled;
|
@include show-tooltip-on-hover;
|
||||||
|
|
||||||
|
.WalletButton-inner {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-inner {
|
||||||
|
transition: opacity 200ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-title {
|
&-title {
|
||||||
|
|
|
@ -16,6 +16,7 @@ interface OwnProps {
|
||||||
isSecure?: boolean;
|
isSecure?: boolean;
|
||||||
isReadOnly?: boolean;
|
isReadOnly?: boolean;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
|
disableReason?: string;
|
||||||
onClick(walletType: string): void;
|
onClick(walletType: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +24,12 @@ interface StateProps {
|
||||||
isFormatDisabled?: boolean;
|
isFormatDisabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Icon {
|
||||||
|
icon: string;
|
||||||
|
tooltip: string;
|
||||||
|
href?: string;
|
||||||
|
}
|
||||||
|
|
||||||
type Props = OwnProps & StateProps;
|
type Props = OwnProps & StateProps;
|
||||||
|
|
||||||
export class WalletButton extends React.PureComponent<Props> {
|
export class WalletButton extends React.PureComponent<Props> {
|
||||||
|
@ -35,9 +42,37 @@ export class WalletButton extends React.PureComponent<Props> {
|
||||||
helpLink,
|
helpLink,
|
||||||
isSecure,
|
isSecure,
|
||||||
isReadOnly,
|
isReadOnly,
|
||||||
isDisabled
|
isDisabled,
|
||||||
|
disableReason
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const icons: Icon[] = [];
|
||||||
|
if (isReadOnly) {
|
||||||
|
icons.push({
|
||||||
|
icon: 'eye',
|
||||||
|
tooltip: translateRaw('You cannot send using address only')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (isSecure) {
|
||||||
|
icons.push({
|
||||||
|
icon: 'shield',
|
||||||
|
tooltip: translateRaw('This wallet type is secure')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
icons.push({
|
||||||
|
icon: 'exclamation-triangle',
|
||||||
|
tooltip: translateRaw('This wallet type is insecure')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (helpLink) {
|
||||||
|
icons.push({
|
||||||
|
icon: 'question-circle',
|
||||||
|
tooltip: translateRaw('NAV_Help'),
|
||||||
|
href: helpLink
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classnames({
|
className={classnames({
|
||||||
|
@ -49,6 +84,7 @@ export class WalletButton extends React.PureComponent<Props> {
|
||||||
tabIndex={isDisabled ? -1 : 0}
|
tabIndex={isDisabled ? -1 : 0}
|
||||||
aria-disabled={isDisabled}
|
aria-disabled={isDisabled}
|
||||||
>
|
>
|
||||||
|
<div className="WalletButton-inner">
|
||||||
<div className="WalletButton-title">
|
<div className="WalletButton-title">
|
||||||
{icon && <img className="WalletButton-title-icon" src={icon} />}
|
{icon && <img className="WalletButton-title-icon" src={icon} />}
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
|
@ -58,34 +94,23 @@ export class WalletButton extends React.PureComponent<Props> {
|
||||||
{example && <div className="WalletButton-example">{example}</div>}
|
{example && <div className="WalletButton-example">{example}</div>}
|
||||||
|
|
||||||
<div className="WalletButton-icons">
|
<div className="WalletButton-icons">
|
||||||
{isSecure ? (
|
{icons.map(i => (
|
||||||
<span className="WalletButton-icons-icon" onClick={this.stopPropogation}>
|
<span className="WalletButton-icons-icon" key={i.icon} onClick={this.stopPropogation}>
|
||||||
<i className="fa fa-shield" />
|
{i.href ? (
|
||||||
<Tooltip>{translateRaw('This wallet type is secure')}</Tooltip>
|
<NewTabLink href={i.href} onClick={this.stopPropogation}>
|
||||||
</span>
|
<i className={`fa fa-${i.icon}`} />
|
||||||
) : (
|
|
||||||
<span className="WalletButton-icons-icon" onClick={this.stopPropogation}>
|
|
||||||
<i className="fa fa-exclamation-triangle" />
|
|
||||||
<Tooltip>{translateRaw('This wallet type is insecure')}</Tooltip>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{isReadOnly && (
|
|
||||||
<span className="WalletButton-icons-icon" onClick={this.stopPropogation}>
|
|
||||||
<i className="fa fa-eye" />
|
|
||||||
<Tooltip>{translateRaw('You cannot send using address only')}</Tooltip>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{helpLink && (
|
|
||||||
<span className="WalletButton-icons-icon">
|
|
||||||
<NewTabLink href={helpLink} onClick={this.stopPropogation}>
|
|
||||||
<i className="fa fa-question-circle" />
|
|
||||||
</NewTabLink>
|
</NewTabLink>
|
||||||
<Tooltip>{translateRaw('NAV_Help')}</Tooltip>
|
) : (
|
||||||
</span>
|
<i className={`fa fa-${i.icon}`} />
|
||||||
)}
|
)}
|
||||||
|
{!isDisabled && <Tooltip size="sm">{i.tooltip}</Tooltip>}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isDisabled && disableReason && <Tooltip>{disableReason}</Tooltip>}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,31 @@
|
||||||
import { MiscWalletName, SecureWalletName, WalletName } from 'config';
|
import { MiscWalletName, SecureWalletName, WalletName } from 'config';
|
||||||
|
|
||||||
|
export interface DisabledWallets {
|
||||||
|
wallets: WalletName[];
|
||||||
|
reasons: {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
enum WalletMode {
|
enum WalletMode {
|
||||||
READ_ONLY = 'READ_ONLY',
|
READ_ONLY = 'READ_ONLY',
|
||||||
UNABLE_TO_SIGN = 'UNABLE_TO_SIGN',
|
UNABLE_TO_SIGN = 'UNABLE_TO_SIGN'
|
||||||
ONLINE_ONLY = 'ONLINE_ONLY'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const walletModes: { [key in WalletMode]: WalletName[] } = {
|
// Duplicating reasons is kind of tedious, but saves having to run through a
|
||||||
[WalletMode.READ_ONLY]: [MiscWalletName.VIEW_ONLY],
|
// bunch of loops to format it differently
|
||||||
[WalletMode.UNABLE_TO_SIGN]: [SecureWalletName.TREZOR, MiscWalletName.VIEW_ONLY],
|
export const DISABLE_WALLETS: { [key in WalletMode]: DisabledWallets } = {
|
||||||
[WalletMode.ONLINE_ONLY]: [SecureWalletName.WEB3, SecureWalletName.TREZOR]
|
[WalletMode.READ_ONLY]: {
|
||||||
|
wallets: [MiscWalletName.VIEW_ONLY],
|
||||||
|
reasons: {
|
||||||
|
[MiscWalletName.VIEW_ONLY]: 'Read only is not allowed'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[WalletMode.UNABLE_TO_SIGN]: {
|
||||||
|
wallets: [SecureWalletName.TREZOR, MiscWalletName.VIEW_ONLY],
|
||||||
|
reasons: {
|
||||||
|
[SecureWalletName.TREZOR]: 'This wallet can’t sign messages',
|
||||||
|
[MiscWalletName.VIEW_ONLY]: 'This wallet can’t sign messages'
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default walletModes;
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
import WalletDecrypt from './WalletDecrypt';
|
import WalletDecrypt from './WalletDecrypt';
|
||||||
export default WalletDecrypt;
|
export default WalletDecrypt;
|
||||||
export { default as DISABLE_WALLETS } from './disables';
|
export * from './disables';
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
@import 'common/sass/variables';
|
@import 'common/sass/variables';
|
||||||
@import 'common/sass/mixins';
|
@import 'common/sass/mixins';
|
||||||
|
|
||||||
|
$tooltip-bg: rgba(#222, 0.95);
|
||||||
|
|
||||||
.Tooltip {
|
.Tooltip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
font-size: $font-size-xs;
|
font-size: $font-size-small;
|
||||||
font-family: $font-family-sans-serif;
|
font-family: $font-family-sans-serif;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -20,9 +22,9 @@
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: rgba(#000, 0.9);
|
background: $tooltip-bg;
|
||||||
border-radius: 2px;
|
border-radius: 3px;
|
||||||
padding: 4px 8px;
|
padding: 6px 10px;
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -30,7 +32,36 @@
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, 100%);
|
transform: translate(-50%, 100%);
|
||||||
@include triangle(8px, rgba(#000, 0.9), down);
|
@include triangle(10px, $tooltip-bg, down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sizing, medium is default
|
||||||
|
&.is-size-sm {
|
||||||
|
width: 200px;
|
||||||
|
font-size: $font-size-xs;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
@include triangle(8px, $tooltip-bg, down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-size-lg {
|
||||||
|
width: 240px;
|
||||||
|
font-size: $font-size-base;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
@include triangle(12px, $tooltip-bg, down);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
import './Tooltip.scss';
|
import './Tooltip.scss';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: React.ReactElement<string> | string;
|
children: React.ReactElement<string> | string;
|
||||||
|
size?: 'sm' | 'md' | 'lg';
|
||||||
}
|
}
|
||||||
|
|
||||||
const Tooltip: React.SFC<Props> = ({ children }) => (
|
const Tooltip: React.SFC<Props> = ({ size, children }) => (
|
||||||
<div className="Tooltip">
|
<div
|
||||||
|
className={classnames({
|
||||||
|
Tooltip: true,
|
||||||
|
[`is-size-${size}`]: !!size
|
||||||
|
})}
|
||||||
|
>
|
||||||
<span className="Tooltip-text">{children}</span>
|
<span className="Tooltip-text">{children}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,15 +2,14 @@ import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import translate, { TranslateType } from 'translations';
|
import translate, { TranslateType } from 'translations';
|
||||||
import WalletDecrypt from 'components/WalletDecrypt';
|
import WalletDecrypt, { DisabledWallets } from 'components/WalletDecrypt';
|
||||||
import { IWallet } from 'libs/wallet/IWallet';
|
import { IWallet } from 'libs/wallet/IWallet';
|
||||||
import './UnlockHeader.scss';
|
import './UnlockHeader.scss';
|
||||||
import { WalletName } from 'config';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: TranslateType;
|
title: TranslateType;
|
||||||
wallet: IWallet;
|
wallet: IWallet;
|
||||||
disabledWallets?: WalletName[];
|
disabledWallets?: DisabledWallets;
|
||||||
showGenerateLink?: boolean;
|
showGenerateLink?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import WalletDecrypt from 'components/WalletDecrypt';
|
import WalletDecrypt, { DISABLE_WALLETS } from 'components/WalletDecrypt';
|
||||||
import { OnlyUnlocked } from 'components/renderCbs';
|
import { OnlyUnlocked } from 'components/renderCbs';
|
||||||
import { Fields } from './Fields';
|
import { Fields } from './Fields';
|
||||||
import { isUnlocked as isUnlockedSelector } from 'selectors/wallet';
|
import { isUnlocked as isUnlockedSelector } from 'selectors/wallet';
|
||||||
|
@ -41,7 +41,11 @@ class LiteSendClass extends Component<Props> {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
renderMe = isUnlocked ? <OnlyUnlocked whenUnlocked={<Fields />} /> : <WalletDecrypt />;
|
renderMe = isUnlocked ? (
|
||||||
|
<OnlyUnlocked whenUnlocked={<Fields />} />
|
||||||
|
) : (
|
||||||
|
<WalletDecrypt disabledWallets={DISABLE_WALLETS.READ_ONLY} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <React.Fragment>{renderMe}</React.Fragment>;
|
return <React.Fragment>{renderMe}</React.Fragment>;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { TokenValue, Wei } from 'libs/units';
|
import { TokenValue, Wei } from 'libs/units';
|
||||||
import { Token } from 'config';
|
import { Token, SecureWalletName, WalletName } from 'config';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { getNetworkConfig } from 'selectors/config';
|
import { getNetworkConfig, getOffline } from 'selectors/config';
|
||||||
import { IWallet, Web3Wallet, LedgerWallet, TrezorWallet, WalletConfig } from 'libs/wallet';
|
import { IWallet, Web3Wallet, LedgerWallet, TrezorWallet, WalletConfig } from 'libs/wallet';
|
||||||
import { isEtherTransaction, getUnit } from './transaction';
|
import { isEtherTransaction, getUnit } from './transaction';
|
||||||
|
import { unSupportedWalletFormatsOnNetwork } from 'utils/network';
|
||||||
|
import { DisabledWallets } from 'components/WalletDecrypt';
|
||||||
|
|
||||||
export function getWalletInst(state: AppState): IWallet | null | undefined {
|
export function getWalletInst(state: AppState): IWallet | null | undefined {
|
||||||
return state.wallet.inst;
|
return state.wallet.inst;
|
||||||
|
@ -139,3 +141,56 @@ export function getShownTokenBalances(
|
||||||
|
|
||||||
return tokenBalances.filter(t => walletTokens.includes(t.symbol));
|
return tokenBalances.filter(t => walletTokens.includes(t.symbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Convert to reselect selector (Issue #884)
|
||||||
|
export function getDisabledWallets(state: AppState): DisabledWallets {
|
||||||
|
const network = getNetworkConfig(state);
|
||||||
|
const isOffline = getOffline(state);
|
||||||
|
const disabledWallets: DisabledWallets = {
|
||||||
|
wallets: [],
|
||||||
|
reasons: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const addReason = (wallets: WalletName[], reason: string) => {
|
||||||
|
if (!wallets.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
disabledWallets.wallets = disabledWallets.wallets.concat(wallets);
|
||||||
|
wallets.forEach(wallet => {
|
||||||
|
disabledWallets.reasons[wallet] = reason;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Some wallets don't support some networks
|
||||||
|
addReason(
|
||||||
|
unSupportedWalletFormatsOnNetwork(network),
|
||||||
|
`${network.name} does not support this wallet`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Some wallets are unavailable offline
|
||||||
|
if (isOffline) {
|
||||||
|
addReason(
|
||||||
|
[SecureWalletName.WEB3, SecureWalletName.TREZOR],
|
||||||
|
'This wallet cannot be accessed offline'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some wallets are disabled on certain platforms
|
||||||
|
if (process.env.BUILD_DOWNLOADABLE) {
|
||||||
|
addReason(
|
||||||
|
[SecureWalletName.LEDGER_NANO_S],
|
||||||
|
'This wallet is only supported at MyEtherWallet.com'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (process.env.BUILD_ELECTRON) {
|
||||||
|
addReason([SecureWalletName.WEB3], 'This wallet is not supported in the MyEtherWallet app');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dedupe and sort for consistency
|
||||||
|
disabledWallets.wallets = disabledWallets.wallets
|
||||||
|
.filter((name, idx) => disabledWallets.wallets.indexOf(name) === idx)
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
return disabledWallets;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue