Translation Updates (#1323)
* Update account view routing * Temporarily add unicode character to translated strings for testing * Temporarily select add unicode to all untranslated strings * Format changes * Add all english translations for /account & /generate * Add the rest of the english translations * Add a few more missing translations * Update en translations * Get selectedLanguage from localstorage instead of redux sttate * Update snapshots * Add missing translation keys & Update translate functs & change variable prefix * translate all markdown strings & remove old translation strings * Update snapshot * Add a few more translation strs * Move raw strings being translated into json * All translation keys are now Uppercase * Fix up the last few translations * Update snapshot * Uppercase de translation strings * Bring back shapeshift logo on swap * Fix contracts tab translations * Fix a few more translations * Fix translations * remove debugging stuff * Update snapshots * Use react.fragment as markdown root renderer * Seperate markdown translations into their own function * Clean up translation functions * Clean up translation functions * Update snapshot * Fix some broken translation strings * Add prettier ignore file
This commit is contained in:
parent
7521337bda
commit
816ce3180f
|
@ -0,0 +1 @@
|
|||
common/translations
|
|
@ -13,7 +13,7 @@ export const AddressField: React.SFC<Props> = ({ isReadOnly }) => (
|
|||
withProps={({ currentTo, isValid, onChange, readOnly }) => (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('SEND_addr')}</div>
|
||||
<div className="input-group-header">{translate('SEND_ADDR_SHORT')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${isValid ? '' : 'invalid'}`}
|
||||
type="text"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { AmountFieldFactory } from './AmountFieldFactory';
|
||||
import { UnitDropDown } from 'components';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import translate from 'translations';
|
||||
import { Input } from 'components/ui';
|
||||
|
||||
interface Props {
|
||||
|
@ -19,13 +19,13 @@ export const AmountField: React.SFC<Props> = ({
|
|||
withProps={({ currentValue: { raw }, isValid, onChange, readOnly }) => (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group input-group-inline">
|
||||
<div className="input-group-header">{translate('SEND_amount')}</div>
|
||||
<div className="input-group-header">{translate('SEND_AMOUNT_SHORT')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${
|
||||
isAmountValid(raw, customValidator, isValid) ? '' : 'invalid'
|
||||
}`}
|
||||
type="number"
|
||||
placeholder={translateRaw('SEND_amount_short')}
|
||||
placeholder={'1'}
|
||||
value={raw}
|
||||
readOnly={!!readOnly}
|
||||
onChange={onChange}
|
||||
|
|
|
@ -98,7 +98,7 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
const wallet = this.props.wallet as LedgerWallet | TrezorWallet;
|
||||
return (
|
||||
<div className="AccountInfo">
|
||||
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountAddr')}</h5>
|
||||
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_ACCOUNTADDR')}</h5>
|
||||
<div className="AccountInfo-section AccountInfo-address-section">
|
||||
<div className="AccountInfo-address-icon">
|
||||
<Identicon address={address} size="100%" />
|
||||
|
@ -134,7 +134,9 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
});
|
||||
}}
|
||||
>
|
||||
{confirmAddr ? null : 'Display address on ' + wallet.getWalletType()}
|
||||
{confirmAddr
|
||||
? null
|
||||
: translate('SIDEBAR_DISPLAY_ADDR', { $wallet: wallet.getWalletType() })}
|
||||
</a>
|
||||
{confirmAddr ? (
|
||||
<span className="AccountInfo-address-confirm">
|
||||
|
@ -145,7 +147,7 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
)}
|
||||
|
||||
<div className="AccountInfo-section">
|
||||
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountBal')}</h5>
|
||||
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_ACCOUNTBAL')}</h5>
|
||||
<ul className="AccountInfo-list">
|
||||
<li className="AccountInfo-list-item AccountInfo-balance">
|
||||
<span
|
||||
|
@ -182,7 +184,7 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
|
||||
{(!!blockExplorer || !!tokenExplorer) && (
|
||||
<div className="AccountInfo-section">
|
||||
<h5 className="AccountInfo-section-header">{translate('sidebar_TransHistory')}</h5>
|
||||
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_TRANSHISTORY')}</h5>
|
||||
<ul className="AccountInfo-list">
|
||||
{!!blockExplorer && (
|
||||
<li className="AccountInfo-list-item">
|
||||
|
|
|
@ -169,7 +169,7 @@ class EquivalentValues extends React.Component<Props, State> {
|
|||
return (
|
||||
<div className="EquivalentValues">
|
||||
<div className="EquivalentValues-header">
|
||||
<h5 className="EquivalentValues-title">{translate('sidebar_Equiv')}</h5>
|
||||
<h5 className="EquivalentValues-title">{translate('SIDEBAR_EQUIV')}</h5>
|
||||
<Select
|
||||
name="equivalentValues"
|
||||
// TODO: Update type
|
||||
|
@ -183,13 +183,11 @@ class EquivalentValues extends React.Component<Props, State> {
|
|||
|
||||
{isOffline ? (
|
||||
<div className="EquivalentValues-offline well well-sm">
|
||||
Equivalent values are unavailable offline
|
||||
{translate('EQUIV_VALS_OFFLINE')}
|
||||
</div>
|
||||
) : network.isTestnet ? (
|
||||
<div className="text-center">
|
||||
<h5 style={{ color: 'red' }}>
|
||||
On test network, equivalent values will not be displayed.
|
||||
</h5>
|
||||
<h5 style={{ color: 'red' }}>{translate('EQUIV_VALS_TESTNET')}</h5>
|
||||
</div>
|
||||
) : ratesError ? (
|
||||
<h5>{ratesError}</h5>
|
||||
|
@ -228,7 +226,7 @@ class EquivalentValues extends React.Component<Props, State> {
|
|||
)}
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<p>Sorry, equivalent values are not supported for this unit.</p>
|
||||
<p>{translate('EQUIV_VALS_UNSUPPORTED_UNIT')}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { HELP_ARTICLE } from 'config';
|
||||
import { isPositiveIntegerOrZero, isValidETHAddress } from 'libs/validators';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { HelpLink, Input } from 'components/ui';
|
||||
import './AddCustomTokenForm.scss';
|
||||
import { Token } from 'types/network';
|
||||
|
@ -47,17 +47,17 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
|
|||
{
|
||||
name: 'symbol',
|
||||
value: symbol,
|
||||
label: translate('TOKEN_Symbol')
|
||||
label: translateRaw('TOKEN_SYMBOL')
|
||||
},
|
||||
{
|
||||
name: 'address',
|
||||
value: address,
|
||||
label: translate('TOKEN_Addr')
|
||||
label: translateRaw('TOKEN_ADDR')
|
||||
},
|
||||
{
|
||||
name: 'decimal',
|
||||
value: decimal,
|
||||
label: translate('TOKEN_Dec')
|
||||
label: translateRaw('TOKEN_DEC')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -84,20 +84,20 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
|
|||
})}
|
||||
|
||||
<HelpLink article={HELP_ARTICLE.ADDING_NEW_TOKENS} className="AddCustom-buttons-help">
|
||||
{translate('Need help? Learn how to add custom tokens.')}
|
||||
{translate('ADD_CUSTOM_TKN_HELP')}
|
||||
</HelpLink>
|
||||
<div className="AddCustom-buttons">
|
||||
<button
|
||||
className="AddCustom-buttons-btn btn btn-sm btn-default"
|
||||
onClick={this.props.toggleForm}
|
||||
>
|
||||
{translate('x_Cancel')}
|
||||
{translate('ACTION_2')}
|
||||
</button>
|
||||
<button
|
||||
className="AddCustom-buttons-btn btn btn-primary btn-sm"
|
||||
disabled={!this.isValid()}
|
||||
>
|
||||
{translate('x_Save')}
|
||||
{translate('X_SAVE')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -50,11 +50,9 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
|
|||
bottom = (
|
||||
<div className="TokenBalances-buttons">
|
||||
<button className="btn btn-primary btn-block" onClick={this.handleSetWalletTokens}>
|
||||
<span>{translate('x_Save')}</span>
|
||||
<span>{translate('X_SAVE')}</span>
|
||||
</button>
|
||||
<p className="TokenBalances-buttons-help">
|
||||
{translate('Missing tokens? You can add custom tokens next.')}
|
||||
</p>
|
||||
<p className="TokenBalances-buttons-help">{translate('PROMPT_ADD_CUSTOM_TKN')}</p>
|
||||
</div>
|
||||
);
|
||||
} else if (showCustomTokenForm) {
|
||||
|
@ -71,10 +69,10 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
|
|||
bottom = (
|
||||
<div className="TokenBalances-buttons">
|
||||
<button className="btn btn-default btn-xs" onClick={this.toggleShowCustomTokenForm}>
|
||||
<span>{translate('SEND_custom')}</span>
|
||||
</button>{' '}
|
||||
<span>{translate('SEND_CUSTOM')}</span>
|
||||
</button>
|
||||
<button className="btn btn-default btn-xs" onClick={this.props.scanWalletForTokens}>
|
||||
<span>Scan for New Tokens</span>
|
||||
<span>{translate('SCAN_TOKENS')}</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -105,7 +103,7 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
|
|||
</tbody>
|
||||
</table>
|
||||
) : (
|
||||
<div className="well well-sm text-center">No tokens found</div>
|
||||
<div className="well well-sm text-center">{translate('SCAN_TOKENS_FAIL_NO_TOKENS')}</div>
|
||||
)}
|
||||
{bottom}
|
||||
</div>
|
||||
|
|
|
@ -74,7 +74,7 @@ class TokenBalances extends React.Component<Props> {
|
|||
className="TokenBalances-scan btn btn-primary btn-block"
|
||||
onClick={this.scanWalletForTokens}
|
||||
>
|
||||
{translate('Scan for my Tokens')}
|
||||
{translate('SCAN_TOKENS')}
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
|
@ -95,7 +95,7 @@ class TokenBalances extends React.Component<Props> {
|
|||
|
||||
return (
|
||||
<section className="TokenBalances">
|
||||
<h5 className="TokenBalances-title">{translate('sidebar_TokenBal')}</h5>
|
||||
<h5 className="TokenBalances-title">{translate('SIDEBAR_TOKENBAL')}</h5>
|
||||
{content}
|
||||
</section>
|
||||
);
|
||||
|
|
|
@ -7,6 +7,7 @@ import { AppState } from 'reducers';
|
|||
import './Body.scss';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import { NetworkConfig } from 'types/network';
|
||||
import translate from 'translations';
|
||||
|
||||
interface State {
|
||||
showDetails: boolean;
|
||||
|
@ -43,7 +44,7 @@ class BodyClass extends React.Component<StateProps, State> {
|
|||
}`}
|
||||
onClick={this.toggleDetails}
|
||||
>
|
||||
Details
|
||||
{translate('ACTION_8')}
|
||||
</button>
|
||||
{showDetails && <Details />}
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { SerializedTransaction } from 'components/renderCbs';
|
|||
import { AppState } from 'reducers';
|
||||
import { getFrom, getUnit, isEtherTransaction } from 'selectors/transaction';
|
||||
import { toChecksumAddress } from 'ethereumjs-util';
|
||||
import translate from 'translations';
|
||||
|
||||
interface StateProps {
|
||||
from: AppState['transaction']['meta']['from'];
|
||||
|
@ -35,7 +36,7 @@ class AddressesClass extends Component<StateProps> {
|
|||
<Identicon className="tx-modal-address-from-icon" size={size} address={from} />
|
||||
)}
|
||||
<div className="tx-modal-address-from-content">
|
||||
<h5 className="tx-modal-address-from-title">From </h5>
|
||||
<h5 className="tx-modal-address-from-title">{translate('CONFIRM_TX_FROM')} </h5>
|
||||
<h5 className="tx-modal-address-from-address small">{from}</h5>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,7 +46,9 @@ class AddressesClass extends Component<StateProps> {
|
|||
<img src={arrow} alt="arrow" />
|
||||
</div>
|
||||
<div className="tx-modal-address-tkn-contract-content">
|
||||
<p className="tx-modal-address-tkn-contract-title">via the {unit} contract</p>
|
||||
<p className="tx-modal-address-tkn-contract-title">
|
||||
{translate('CONFIRM_TX_VIA_CONTRACT', { unit })}
|
||||
</p>
|
||||
<a
|
||||
className="small tx-modal-address-tkn-contract-link"
|
||||
href={ETHAddressExplorer(to)}
|
||||
|
@ -62,7 +65,7 @@ class AddressesClass extends Component<StateProps> {
|
|||
address={toFormatted}
|
||||
/>
|
||||
<div className="tx-modal-address-to-content">
|
||||
<h5 className="tx-modal-address-to-title">To </h5>
|
||||
<h5 className="tx-modal-address-to-title">{translate('CONFIRM_TX_TO')} </h5>
|
||||
<h5 className="small tx-modal-address-to-address">{toFormatted}</h5>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { SerializedTxParams, getParamsFromSerializedTx } from 'selectors/transac
|
|||
import { connect } from 'react-redux';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import { NetworkConfig } from 'types/network';
|
||||
import translate from 'translations';
|
||||
|
||||
interface StateProps extends SerializedTxParams, AllUSDValues {
|
||||
network: NetworkConfig;
|
||||
|
@ -32,7 +33,7 @@ class AmountsClass extends Component<StateProps> {
|
|||
<table className="tx-modal-amount">
|
||||
<tbody>
|
||||
<tr className="tx-modal-amount-send">
|
||||
<td>You'll Send</td>
|
||||
<td>{translate('CONFIRM_TX_SENDING')}</td>
|
||||
<td>
|
||||
<UnitDisplay
|
||||
value={currentValue}
|
||||
|
@ -54,7 +55,7 @@ class AmountsClass extends Component<StateProps> {
|
|||
)}
|
||||
</tr>
|
||||
<tr className="tx-modal-amount-fee">
|
||||
<td>Transaction Fee</td>
|
||||
<td>{translate('CONFIRM_TX_FEE')}</td>
|
||||
<td>
|
||||
<UnitDisplay
|
||||
value={fee}
|
||||
|
@ -77,7 +78,7 @@ class AmountsClass extends Component<StateProps> {
|
|||
</tr>
|
||||
{!isToken && (
|
||||
<tr className="tx-modal-amount-total">
|
||||
<td>Total</td>
|
||||
<td>{translate('CONFIRM_TX_TOTAL')}</td>
|
||||
<td>
|
||||
<UnitDisplay
|
||||
value={total}
|
||||
|
|
|
@ -11,9 +11,9 @@ import {
|
|||
TBroadcastWeb3TransactionRequested
|
||||
} from 'actions/transaction';
|
||||
import { currentTransactionBroadcasting } from 'selectors/transaction';
|
||||
import { translateRaw } from 'translations';
|
||||
import './ConfirmationModalTemplate.scss';
|
||||
import { AppState } from 'reducers';
|
||||
import { translateRaw, translate } from 'translations';
|
||||
|
||||
interface DispatchProps {
|
||||
broadcastLocalTransactionRequested: TBroadcastLocalTransactionRequested;
|
||||
|
@ -73,7 +73,7 @@ class ConfirmationModalTemplateClass extends React.Component<Props, State> {
|
|||
const { timeToRead } = this.state;
|
||||
const buttonPrefix = timeToRead > 0 ? `(${timeToRead}) ` : '';
|
||||
const defaultConfirmButton = {
|
||||
text: buttonPrefix + translateRaw('SENDModal_Yes'),
|
||||
text: buttonPrefix + translateRaw('ACTION_11'),
|
||||
type: 'primary' as IButton['type'],
|
||||
disabled: timeToRead > 0,
|
||||
onClick: this.confirm
|
||||
|
@ -85,7 +85,7 @@ class ConfirmationModalTemplateClass extends React.Component<Props, State> {
|
|||
timeLeft: timeToRead,
|
||||
timePrefix: buttonPrefix,
|
||||
timeLocked: defaultConfirmButton.disabled,
|
||||
defaultText: translateRaw('SENDModal_Yes'),
|
||||
defaultText: translateRaw('ACTION_11'),
|
||||
type: defaultConfirmButton.type
|
||||
})
|
||||
: defaultConfirmButton;
|
||||
|
@ -93,7 +93,7 @@ class ConfirmationModalTemplateClass extends React.Component<Props, State> {
|
|||
const buttons: IButton[] = [
|
||||
confirmButton,
|
||||
{
|
||||
text: translateRaw('SENDModal_No'),
|
||||
text: translate('ACTION_2'),
|
||||
type: 'default',
|
||||
onClick: onClose
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ class ConfirmationModalTemplateClass extends React.Component<Props, State> {
|
|||
|
||||
return (
|
||||
<Modal
|
||||
title="Confirm Transaction"
|
||||
title={translateRaw('CONFIRM_TX_MODAL_TITLE')}
|
||||
buttons={buttons}
|
||||
handleClose={onClose}
|
||||
disableButtons={transactionBroadcasting}
|
||||
|
|
|
@ -9,7 +9,7 @@ export const DataField: React.SFC<{}> = () => (
|
|||
withProps={({ data: { raw }, dataExists, onChange, readOnly }) => (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('OFFLINE_Step2_Label_6')}</div>
|
||||
<div className="input-group-header">{translate('OFFLINE_STEP2_LABEL_6')}</div>
|
||||
<Input
|
||||
className={dataExists ? 'is-valid' : 'is-invalid'}
|
||||
type="text"
|
||||
|
|
|
@ -14,7 +14,7 @@ const TransactionSucceeded = ({ txHash, blockExplorer }: TransactionSucceededPro
|
|||
if (blockExplorer) {
|
||||
verifyBtn = (
|
||||
<NewTabLink className="btn btn-xs" href={blockExplorer.txUrl(txHash)}>
|
||||
Verify Transaction on {blockExplorer.name}
|
||||
{translate('VERIFY_TX', { $block_explorer: blockExplorer.name })}
|
||||
</NewTabLink>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import Modal, { IButton } from 'components/ui/Modal';
|
|||
import { HelpLink } from 'components/ui';
|
||||
import { HELP_ARTICLE } from 'config';
|
||||
import './DisclaimerModal.scss';
|
||||
import translate from 'translations';
|
||||
|
||||
interface Props {
|
||||
isOpen: boolean;
|
||||
|
@ -10,7 +11,9 @@ interface Props {
|
|||
}
|
||||
|
||||
const DisclaimerModal: React.SFC<Props> = ({ isOpen, handleClose }) => {
|
||||
const buttons: IButton[] = [{ text: 'Okay', type: 'default', onClick: handleClose }];
|
||||
const buttons: IButton[] = [
|
||||
{ text: translate('ACTION_10'), type: 'default', onClick: handleClose }
|
||||
];
|
||||
return (
|
||||
<Modal isOpen={isOpen} title="Disclaimer" buttons={buttons} handleClose={handleClose}>
|
||||
<p>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import './PreFooter.scss';
|
||||
import translate from 'translations';
|
||||
|
||||
interface Props {
|
||||
openModal(): void;
|
||||
|
@ -10,9 +11,8 @@ const PreFooter: React.SFC<Props> = ({ openModal }) => {
|
|||
<section className="pre-footer">
|
||||
<div className="container">
|
||||
<p>
|
||||
MyCrypto.com does not hold your keys for you. We cannot access accounts, recover keys,
|
||||
reset passwords, nor reverse transactions. Protect your keys & always check that you are
|
||||
on correct URL. <a onClick={openModal}>You are responsible for your security.</a>
|
||||
{translate('PREFOOTER_WARNING')}{' '}
|
||||
<a onClick={openModal}>{translate('PREFOOTER_SECURITY_WARNING')}</a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -14,6 +14,7 @@ import DisclaimerModal from './DisclaimerModal';
|
|||
import { NewTabLink } from 'components/ui';
|
||||
import OnboardModal from 'containers/OnboardModal';
|
||||
import './index.scss';
|
||||
import { translateRaw } from 'translations';
|
||||
|
||||
const SocialMediaLink = ({ link, text }: Link) => {
|
||||
return (
|
||||
|
@ -58,39 +59,39 @@ const PRODUCT_INFO: Link[] = [
|
|||
{
|
||||
link:
|
||||
'https://chrome.google.com/webstore/detail/etheraddresslookup/pdknmigbbbhmllnmgdfalmedcmcefdfn',
|
||||
text: 'Ether Address Lookup'
|
||||
text: translateRaw('ETHER_ADDRESS_LOOKUP')
|
||||
},
|
||||
{
|
||||
link:
|
||||
'https://chrome.google.com/webstore/detail/ethersecuritylookup/bhhfhgpgmifehjdghlbbijjaimhmcgnf',
|
||||
text: 'Ether Security Lookup'
|
||||
text: translateRaw('ETHER_SECURITY_LOOKUP')
|
||||
},
|
||||
{
|
||||
link: 'https://etherscamdb.info/',
|
||||
text: 'EtherScamDB'
|
||||
text: translateRaw('ETHERSCAMDB')
|
||||
},
|
||||
{
|
||||
link: 'https://www.mycrypto.com/helpers.html',
|
||||
text: 'Helpers & ENS Debugging'
|
||||
text: translateRaw('FOOTER_HELP_AND_DEBUGGING')
|
||||
},
|
||||
{
|
||||
link: 'mailto:press@mycrypto.com',
|
||||
text: 'Press Inquiries'
|
||||
text: translateRaw('FOOTER_PRESS')
|
||||
}
|
||||
];
|
||||
|
||||
const AFFILIATES: Link[] = [
|
||||
{
|
||||
link: ledgerReferralURL,
|
||||
text: 'Buy a Ledger Wallet'
|
||||
text: translateRaw('LEDGER_REFERAL_1')
|
||||
},
|
||||
{
|
||||
link: trezorReferralURL,
|
||||
text: 'Buy a TREZOR'
|
||||
text: translateRaw('TREZOR_REFERAL')
|
||||
},
|
||||
{
|
||||
link: ethercardReferralURL,
|
||||
text: 'Get an ether.card'
|
||||
text: translateRaw('ETHERCARD_REFERAL')
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -165,51 +166,52 @@ export default class Footer extends React.PureComponent<Props, State> {
|
|||
|
||||
<div className="Footer-about-links">
|
||||
<a href="https://mycrypto.com">MyCrypto.com</a>
|
||||
<NewTabLink href={knowledgeBaseURL}>Help & Support</NewTabLink>
|
||||
<NewTabLink href="https://about.mycrypto.com">Our Team</NewTabLink>
|
||||
<NewTabLink href={knowledgeBaseURL}>{translateRaw('FOOTER_SUPPORT')}</NewTabLink>
|
||||
<NewTabLink href="https://about.mycrypto.com">
|
||||
{translateRaw('FOOTER_TEAM')}
|
||||
</NewTabLink>
|
||||
</div>
|
||||
|
||||
<p className="Footer-about-text">
|
||||
MyCrypto is an open-source, client-side tool for generating Ether Wallets, handling
|
||||
ERC-20 tokens, and interacting with the blockchain more easily. Developed by and for
|
||||
the community since 2015, we’re focused on building awesome products that put the
|
||||
power in people’s hands.
|
||||
</p>
|
||||
<p className="Footer-about-text">{translateRaw('FOOTER_ABOUT')}</p>
|
||||
|
||||
<div className="Footer-about-legal">
|
||||
<div className="Footer-about-legal-text">
|
||||
© {new Date().getFullYear()} MyCrypto, Inc.
|
||||
</div>
|
||||
<div className="Footer-about-legal-text">
|
||||
<a onClick={this.toggleModal}>Disclaimer</a>
|
||||
<a onClick={this.toggleModal}>{translateRaw('DISCLAIMER')}</a>
|
||||
</div>
|
||||
<div className="Footer-about-legal-text">v{VERSION}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="Footer-support Footer-section">
|
||||
<h5 className="Footer-support-title">Support Us & Our Friends</h5>
|
||||
<h5 className="Footer-support-title">{translateRaw('FOOTER_AFFILIATE_TITLE')}</h5>
|
||||
<div className="Footer-support-affiliates">
|
||||
{AFFILIATES.map(link => (
|
||||
<NewTabLink key={link.text} href={link.link}>
|
||||
{AFFILIATES.map((link, i) => (
|
||||
<NewTabLink key={i} href={link.link}>
|
||||
{link.text}
|
||||
</NewTabLink>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="Footer-support-donate">
|
||||
<div className="Footer-support-donate-currency">Donate ETH</div>
|
||||
<div className="Footer-support-donate-currency">
|
||||
{translateRaw('DONATE_CURRENCY', { $currency: 'ETH' })}
|
||||
</div>
|
||||
<div className="Footer-support-donate-address">{donationAddressMap.ETH}</div>
|
||||
</div>
|
||||
|
||||
<div className="Footer-support-donate">
|
||||
<div className="Footer-support-donate-currency">Donate BTC</div>
|
||||
<div className="Footer-support-donate-currency">
|
||||
{translateRaw('DONATE_CURRENCY', { $currency: 'BTC' })}
|
||||
</div>
|
||||
<div className="Footer-support-donate-address">{donationAddressMap.BTC}</div>
|
||||
</div>
|
||||
|
||||
<div className="Footer-support-friends">
|
||||
{FRIENDS.map(link => (
|
||||
<NewTabLink key={link.text} href={link.link}>
|
||||
{FRIENDS.map((link, i) => (
|
||||
<NewTabLink key={i} href={link.link}>
|
||||
{link.text}
|
||||
</NewTabLink>
|
||||
))}
|
||||
|
|
|
@ -17,14 +17,14 @@ export const GasLimitField: React.SFC<Props> = ({ customLabel, disabled }) => (
|
|||
<div className="input-group-wrapper AdvancedGas-gas-price">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">
|
||||
{customLabel ? customLabel : translate('TRANS_gas')}
|
||||
{customLabel ? customLabel : translate('TRANS_GAS')}
|
||||
<div className="flex-spacer" />
|
||||
<InlineSpinner active={gasEstimationPending} text="Calculating" />
|
||||
</div>
|
||||
<Input
|
||||
className={gasLimitValidator(raw) ? 'is-valid' : 'is-invalid'}
|
||||
type="number"
|
||||
placeholder="e.g. 21000"
|
||||
placeholder="21000"
|
||||
readOnly={!!readOnly}
|
||||
value={raw}
|
||||
onChange={onChange}
|
||||
|
|
|
@ -55,14 +55,14 @@ export default class GenerateKeystoreModal extends React.Component<Props, State>
|
|||
|
||||
return (
|
||||
<Modal
|
||||
title={translateRaw('Generate Keystore File')}
|
||||
title={translateRaw('GENERATE_KEYSTORE_ACTION')}
|
||||
isOpen={this.props.isOpen}
|
||||
handleClose={this.handleClose}
|
||||
>
|
||||
<form className="GenKeystore" onSubmit={this.handleSubmit}>
|
||||
<div className="input-group-wrapper GenKeystore-field">
|
||||
<label className="input-group input-group-inline">
|
||||
<div className="input-group-header">Private Key</div>
|
||||
<div className="input-group-header">{translate('X_PRIVKEY2')}</div>
|
||||
<TogglablePassword
|
||||
name="privateKey"
|
||||
value={privateKey}
|
||||
|
@ -75,12 +75,14 @@ export default class GenerateKeystoreModal extends React.Component<Props, State>
|
|||
</div>
|
||||
<div className="input-group-wrapper GenKeystore-field">
|
||||
<label className="input-group input-group-inline">
|
||||
<div className="input-group-header">Password</div>
|
||||
<div className="input-group-header">{translate('INPUT_PASSWORD_LABEL')}</div>
|
||||
<TogglablePassword
|
||||
name="password"
|
||||
value={password}
|
||||
onChange={this.handleInput}
|
||||
placeholder={translateRaw('Minimum 9 characters')}
|
||||
placeholder={translateRaw('INPUT_PASSWORD_PLACEHOLDER', {
|
||||
$pass_length: MINIMUM_PASSWORD_LENGTH.toString()
|
||||
})}
|
||||
isValid={isPasswordValid}
|
||||
/>
|
||||
</label>
|
||||
|
@ -91,24 +93,20 @@ export default class GenerateKeystoreModal extends React.Component<Props, State>
|
|||
className="GenKeystore-button btn btn-primary btn-block"
|
||||
disabled={!isPrivateKeyValid || !isPasswordValid}
|
||||
>
|
||||
{translate('Generate Keystore File')}
|
||||
{translate('GENERATE_KEYSTORE_ACTION')}
|
||||
</button>
|
||||
) : hasError ? (
|
||||
<p className="alert alert-danger">
|
||||
Keystore generation failed or was invalid. In order to prevent loss of funds, we
|
||||
cannot provide you with a keystore file that may be corrupted. Refresh the page or use
|
||||
a different browser, and try again.
|
||||
</p>
|
||||
<p className="alert alert-danger">{translate('GENERATE_KEYSTORE_FAILED')}</p>
|
||||
) : (
|
||||
<a
|
||||
onClick={this.handleClose}
|
||||
href={keystoreFile.blob}
|
||||
className="GenKeystore-button btn btn-success btn-block"
|
||||
aria-label={translateRaw('x_Keystore')}
|
||||
aria-describedby={translateRaw('x_KeystoreDesc')}
|
||||
aria-label={translateRaw('X_KEYSTORE')}
|
||||
aria-describedby={translateRaw('X_KEYSTOREDESC')}
|
||||
download={keystoreFile.filename}
|
||||
>
|
||||
{translate('Download Keystore File')}
|
||||
{translate('ACTION_12')}
|
||||
</a>
|
||||
)}
|
||||
</form>
|
||||
|
|
|
@ -6,7 +6,7 @@ export const GenerateTransaction: React.SFC<{}> = () => (
|
|||
<GenerateTransactionFactory
|
||||
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
|
||||
{isWeb3Wallet ? translate('SEND_generate') : translate('DEP_signtx')}
|
||||
{isWeb3Wallet ? translate('SEND_GENERATE') : translate('DEP_SIGNTX')}
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -84,7 +84,7 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
},
|
||||
{
|
||||
type: 'default',
|
||||
text: translate('x_Cancel'),
|
||||
text: translate('ACTION_2'),
|
||||
onClick: handleClose
|
||||
}
|
||||
];
|
||||
|
@ -105,19 +105,18 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
handleClose={handleClose}
|
||||
maxWidth={580}
|
||||
>
|
||||
{isHttps && <div className="alert alert-warning small">{translate('NODE_Warning')}</div>}
|
||||
{isHttps && <div className="alert alert-warning small">{translate('NODE_WARNING')}</div>}
|
||||
|
||||
{conflictedNode && (
|
||||
<div className="alert alert-warning small">
|
||||
You already have a node called '{conflictedNode.name}' that matches this one, saving
|
||||
this will overwrite it
|
||||
{translate('CUSTOM_NODE_CONFLICT', { conflictedNode: conflictedNode.name })}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form className="CustomNodeModal">
|
||||
<div className="flex-wrapper">
|
||||
<label className="col-sm-9 input-group flex-grow-1">
|
||||
<div className="input-group-header">Node Name</div>
|
||||
<div className="input-group-header">{translate('CUSTOM_NODE_NAME')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${this.state.name && invalids.name ? 'invalid' : ''}`}
|
||||
type="text"
|
||||
|
@ -143,7 +142,7 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
{network === CUSTOM.value && (
|
||||
<div className="flex-wrapper">
|
||||
<label className="col-sm-6 input-group input-group-inline">
|
||||
<div className="input-group-header">Network Name</div>
|
||||
<div className="input-group-header">{translate('CUSTOM_NETWORK_NAME')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${
|
||||
this.state.customNetworkId && invalids.customNetworkId ? 'invalid' : ''
|
||||
|
@ -155,7 +154,7 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
/>
|
||||
</label>
|
||||
<label className="col-sm-3 input-group input-group-inline">
|
||||
<div className="input-group-header">Currency</div>
|
||||
<div className="input-group-header">{translate('CUSTOM_NETWORK_CURRENCY')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${
|
||||
this.state.customNetworkUnit && invalids.customNetworkUnit ? 'invalid' : ''
|
||||
|
@ -167,7 +166,7 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
/>
|
||||
</label>
|
||||
<label className="col-sm-3 input-group input-group-inline">
|
||||
<div className="input-group-header">Chain ID</div>
|
||||
<div className="input-group-header">{translate('CUSTOM_NETWORK_CHAIN_ID')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${
|
||||
this.state.customNetworkChainId && invalids.customNetworkChainId
|
||||
|
@ -184,7 +183,7 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
)}
|
||||
|
||||
<label className="input-group input-group-inline">
|
||||
<div className="input-group-header">URL</div>
|
||||
<div className="input-group-header">{translate('CUSTOM_NETWORK_URL')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${this.state.url && invalids.url ? 'invalid' : ''}`}
|
||||
type="text"
|
||||
|
@ -202,13 +201,13 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
checked={this.state.hasAuth}
|
||||
onChange={() => this.setState({ hasAuth: !this.state.hasAuth })}
|
||||
/>
|
||||
<span>HTTP Basic Authentication</span>
|
||||
<span>{translate('CUSTOM_NETWORK_HTTP_AUTH')}</span>
|
||||
</label>
|
||||
|
||||
{this.state.hasAuth && (
|
||||
<div className="flex-wrapper ">
|
||||
<label className="col-sm-6 input-group input-group-inline">
|
||||
<div className="input-group-header">Username</div>
|
||||
<div className="input-group-header">{translate('INPUT_USERNAME_LABEL')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${
|
||||
this.state.username && invalids.username ? 'invalid' : ''
|
||||
|
@ -219,7 +218,7 @@ class CustomNodeModal extends React.Component<Props, State> {
|
|||
/>
|
||||
</label>
|
||||
<label className="col-sm-6 input-group input-group-inline">
|
||||
<div className="input-group-header">Password</div>
|
||||
<div className="input-group-header">{translate('INPUT_PASSWORD_LABEL')}</div>
|
||||
<Input
|
||||
className={`input-group-input ${
|
||||
this.state.password && invalids.password ? 'invalid' : ''
|
||||
|
|
|
@ -11,19 +11,19 @@ export interface TabLink {
|
|||
|
||||
const tabs: TabLink[] = [
|
||||
{
|
||||
name: 'Account View & Send',
|
||||
name: 'NAV_VIEW',
|
||||
to: '/account'
|
||||
},
|
||||
{
|
||||
name: 'NAV_GenerateWallet',
|
||||
name: 'NAV_GENERATEWALLET',
|
||||
to: '/generate'
|
||||
},
|
||||
{
|
||||
name: 'NAV_Swap',
|
||||
name: 'NAV_SWAP',
|
||||
to: '/swap'
|
||||
},
|
||||
{
|
||||
name: 'NAV_Contracts',
|
||||
name: 'NAV_CONTRACTS',
|
||||
to: '/contracts'
|
||||
},
|
||||
{
|
||||
|
@ -31,19 +31,19 @@ const tabs: TabLink[] = [
|
|||
to: '/ens'
|
||||
},
|
||||
{
|
||||
name: 'Sign & Verify Message',
|
||||
name: 'NAV_SIGN',
|
||||
to: '/sign-and-verify-message'
|
||||
},
|
||||
{
|
||||
name: 'NAV_TxStatus',
|
||||
name: 'NAV_TXSTATUS',
|
||||
to: '/tx-status'
|
||||
},
|
||||
{
|
||||
name: 'Broadcast Transaction',
|
||||
name: 'NAV_BROADCAST',
|
||||
to: '/pushTx'
|
||||
},
|
||||
{
|
||||
name: 'NAV_Help',
|
||||
name: 'NAV_HELP',
|
||||
to: `${knowledgeBaseURL}`,
|
||||
external: true
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@import "common/sass/variables";
|
||||
@import 'common/sass/variables';
|
||||
|
||||
.NavigationLink {
|
||||
display: inline-block;
|
||||
|
@ -14,7 +14,7 @@
|
|||
min-height: 2.75rem;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
content: '';
|
||||
background: $brand-primary;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
|
@ -45,10 +45,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
#NAV_Swap a:before {
|
||||
content:"";
|
||||
#NAV_SWAP a:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
margin-top: -.1rem;
|
||||
margin-top: -0.1rem;
|
||||
width: 1.3rem;
|
||||
height: 1.3rem;
|
||||
background-image: url('~assets/images/logo-shapeshift-no-text.svg');
|
||||
|
|
|
@ -4,6 +4,7 @@ import { withRouter, RouteComponentProps } from 'react-router-dom';
|
|||
import Modal, { IButton } from 'components/ui/Modal';
|
||||
import { AppState } from 'reducers';
|
||||
import { resetWallet, TResetWallet } from 'actions/wallet';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
|
||||
interface Props extends RouteComponentProps<{}> {
|
||||
// State
|
||||
|
@ -42,17 +43,17 @@ class LogOutPromptClass extends React.Component<Props, State> {
|
|||
|
||||
public render() {
|
||||
const buttons: IButton[] = [
|
||||
{ text: 'Log Out', type: 'primary', onClick: this.onConfirm },
|
||||
{ text: 'Cancel', type: 'default', onClick: this.onCancel }
|
||||
{ text: translate('ACTION_7'), type: 'primary', onClick: this.onConfirm },
|
||||
{ text: translate('ACTION_2'), type: 'default', onClick: this.onCancel }
|
||||
];
|
||||
return (
|
||||
<Modal
|
||||
title="You are about to log out"
|
||||
title={translateRaw('WALLET_LOGOUT_MODAL_TITLE')}
|
||||
isOpen={this.state.openModal}
|
||||
handleClose={this.onCancel}
|
||||
buttons={buttons}
|
||||
>
|
||||
<p>Leaving this page will log you out. Are you sure you want to continue?</p>
|
||||
<p>{translate('WALLET_LOGOUT_MODAL_DESC')}</p>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class NonceField extends React.Component<Props> {
|
|||
<div className="input-group-wrapper Nonce-label">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">
|
||||
{translate('OFFLINE_Step2_Label_5')}
|
||||
{translate('OFFLINE_STEP2_LABEL_5')}
|
||||
<Help
|
||||
size="x1"
|
||||
link="https://support.mycrypto.com/transactions/what-is-nonce.html"
|
||||
|
@ -44,7 +44,7 @@ class NonceField extends React.Component<Props> {
|
|||
<Input
|
||||
className={`Nonce-field-input ${!!value ? 'is-valid' : 'is-invalid'}`}
|
||||
type="number"
|
||||
placeholder="e.g. 7"
|
||||
placeholder="7"
|
||||
value={raw}
|
||||
readOnly={readOnly}
|
||||
onChange={onChange}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { PaperWallet } from 'components';
|
||||
import React from 'react';
|
||||
import { translateRaw } from 'translations';
|
||||
import printElement from 'utils/printElement';
|
||||
import { stripHexPrefix } from 'libs/values';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
|
||||
export const print = (address: string, privateKey: string) => () =>
|
||||
address &&
|
||||
|
@ -38,13 +38,13 @@ const PrintableWallet: React.SFC<Props> = ({ address, privateKey }) => {
|
|||
<PaperWallet address={address} privateKey={pkey} />
|
||||
<a
|
||||
role="button"
|
||||
aria-label={translateRaw('x_Print')}
|
||||
aria-label={translateRaw('X_PRINT')}
|
||||
aria-describedby="x_PrintDesc"
|
||||
className="btn btn-lg btn-primary btn-block"
|
||||
onClick={print(address, pkey)}
|
||||
style={{ margin: '10px auto 0', maxWidth: '260px' }}
|
||||
>
|
||||
{translateRaw('x_Print')}
|
||||
{translate('X_PRINT')}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -12,11 +12,11 @@ export const SendButton: React.SFC<{
|
|||
onlyTransactionParameters={!!onlyTransactionParameters}
|
||||
toggleDisabled={toggleDisabled}
|
||||
Modal={customModal ? customModal : ConfirmationModal}
|
||||
withProps={({ disabled, onClick }) => (
|
||||
withProps={({ disabled, onClick }: { disabled: boolean; onClick(): void }) => (
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<button disabled={disabled} className="btn btn-primary btn-block" onClick={onClick}>
|
||||
{translate('SEND_trans')}
|
||||
{translate('SEND_TRANS')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -49,7 +49,7 @@ class SendButtonFactoryClass extends Component<Props> {
|
|||
// shows the json representation of the transaction
|
||||
const leftTxCompare = serializedTransaction && (
|
||||
<div className={`col-sm-${columnSize}`}>
|
||||
<label>{walletType.isWeb3Wallet ? 'Transaction Parameters' : translate('SEND_raw')}</label>
|
||||
<label>{walletType.isWeb3Wallet ? 'Transaction Parameters' : translate('SEND_RAW')}</label>
|
||||
<TextArea value={getStringifiedTx(serializedTransaction)} rows={4} readOnly={true} />
|
||||
</div>
|
||||
);
|
||||
|
@ -63,7 +63,7 @@ class SendButtonFactoryClass extends Component<Props> {
|
|||
<label>
|
||||
{walletType.isWeb3Wallet
|
||||
? 'Serialized Transaction Parameters'
|
||||
: translate('SEND_signed')}
|
||||
: translate('SEND_SIGNED')}
|
||||
</label>
|
||||
<TextArea
|
||||
value={addHexPrefix(serializedTransaction.toString('hex'))}
|
||||
|
|
|
@ -27,7 +27,7 @@ class SendEverythingClass extends Component<Props> {
|
|||
!readOnly ? (
|
||||
<span className="help-block">
|
||||
<a onClick={this.onSendEverything}>
|
||||
<span className="">{translate('SEND_TransferTotal')}</span>
|
||||
<span>{translate('SEND_TRANSFERTOTAL')}</span>
|
||||
</a>
|
||||
</span>
|
||||
) : null
|
||||
|
|
|
@ -3,6 +3,7 @@ import { connect } from 'react-redux';
|
|||
import { AppState } from 'reducers';
|
||||
import { signaturePending } from 'selectors/transaction';
|
||||
import { Spinner } from 'components/ui';
|
||||
import translate from 'translations';
|
||||
interface StateProps {
|
||||
isSignaturePending: boolean;
|
||||
isHardwareWallet: boolean;
|
||||
|
@ -15,7 +16,7 @@ class SigningStatusClass extends Component<StateProps> {
|
|||
const HWWalletPrompt: React.SFC<{}> = _ =>
|
||||
isHardwareWallet ? (
|
||||
<p>
|
||||
<b>Confirm transaction on hardware wallet</b>
|
||||
<b>{translate('CONFIRM_HARDWARE_WALLET_TRANSACTION')}</b>
|
||||
</p>
|
||||
) : null;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import BN from 'bn.js';
|
||||
import { translateRaw } from 'translations';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
inputGasPrice,
|
||||
|
@ -22,6 +21,7 @@ import AdvancedGas, { AdvancedOptions } from './components/AdvancedGas';
|
|||
import './TXMetaDataPanel.scss';
|
||||
import { getGasPrice } from 'selectors/transaction';
|
||||
import { NetworkConfig } from 'types/network';
|
||||
import { translateRaw } from 'translations';
|
||||
|
||||
type SliderStates = 'simple' | 'advanced';
|
||||
|
||||
|
@ -114,8 +114,8 @@ class TXMetaDataPanel extends React.Component<Props, State> {
|
|||
<div className="help-block">
|
||||
<a className="Gas-toggle" onClick={this.toggleAdvanced}>
|
||||
{showAdvanced
|
||||
? `- ${translateRaw('Back to simple')}`
|
||||
: `+ ${translateRaw('Advanced Settings')}`}
|
||||
? `- ${translateRaw('TRANS_SIMPLE')}`
|
||||
: `+ ${translateRaw('TRANS_ADVANCED')}`}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { translateRaw } from 'translations';
|
||||
import FeeSummary from './FeeSummary';
|
||||
import './AdvancedGas.scss';
|
||||
import { TToggleAutoGasLimit, toggleAutoGasLimit } from 'actions/config';
|
||||
|
@ -74,7 +74,7 @@ class AdvancedGas extends React.Component<Props, State> {
|
|||
<div className="input-group-wrapper AdvancedGas-gas-price">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">
|
||||
{translate('OFFLINE_Step2_Label_3')} (gwei)
|
||||
{translateRaw('OFFLINE_STEP2_LABEL_3')} (gwei)
|
||||
</div>
|
||||
<Input
|
||||
className={!!gasPrice.raw && !validGasPrice ? 'is-invalid' : ''}
|
||||
|
@ -89,7 +89,7 @@ class AdvancedGas extends React.Component<Props, State> {
|
|||
|
||||
{gasLimitField && (
|
||||
<div className="AdvancedGas-gas-limit">
|
||||
<GasLimitField customLabel={translateRaw('OFFLINE_Step2_Label_4')} />
|
||||
<GasLimitField customLabel={translateRaw('OFFLINE_STEP2_LABEL_4')} />
|
||||
</div>
|
||||
)}
|
||||
{nonceField && (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import Slider, { createSliderWithTooltip } from 'rc-slider';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import translate from 'translations';
|
||||
import FeeSummary from './FeeSummary';
|
||||
import './SimpleGas.scss';
|
||||
import { AppState } from 'reducers';
|
||||
|
@ -80,7 +80,7 @@ class SimpleGas extends React.Component<Props> {
|
|||
<div className="SimpleGas row form-group">
|
||||
<div className="SimpleGas-title">
|
||||
<div className="flex-wrapper">
|
||||
<label>{translateRaw('Transaction Fee')} </label>
|
||||
<label>{translate('CONFIRM_TX_FEE')} </label>
|
||||
<div className="flex-spacer" />
|
||||
<InlineSpinner active={noncePending || gasLimitPending} text="Calculating" />
|
||||
</div>
|
||||
|
@ -108,8 +108,8 @@ class SimpleGas extends React.Component<Props> {
|
|||
disabled={isGasEstimating}
|
||||
/>
|
||||
<div className="SimpleGas-slider-labels">
|
||||
<span>{translate('Cheap')}</span>
|
||||
<span>{translate('Fast')}</span>
|
||||
<span>{translate('TX_FEE_SCALE_LEFT')}</span>
|
||||
<span>{translate('TX_FEE_SCALE_RIGHT')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<FeeSummary
|
||||
|
|
|
@ -17,7 +17,6 @@ interface Props {
|
|||
toggleAriaLabel?: string;
|
||||
isValid?: boolean;
|
||||
isVisible?: boolean;
|
||||
validity?: 'valid' | 'invalid' | 'semivalid';
|
||||
readOnly?: boolean;
|
||||
|
||||
// Textarea-only props
|
||||
|
@ -56,7 +55,6 @@ export default class TogglablePassword extends React.PureComponent<Props, State>
|
|||
disabled,
|
||||
ariaLabel,
|
||||
toggleAriaLabel,
|
||||
validity,
|
||||
isTextareaWhenVisible,
|
||||
isValid,
|
||||
onChange,
|
||||
|
@ -68,10 +66,10 @@ export default class TogglablePassword extends React.PureComponent<Props, State>
|
|||
const { isVisible } = this.state;
|
||||
|
||||
return (
|
||||
<div className={`TogglablePassword input-group input-group-inline ${className}`}>
|
||||
<div className={`TogglablePassword input-group input-group-inline`}>
|
||||
{isTextareaWhenVisible && isVisible ? (
|
||||
<TextArea
|
||||
className={validity || !isValid ? 'invalid' : ''}
|
||||
className={`${className} ${!isValid ? 'invalid' : ''}`}
|
||||
value={value}
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
|
@ -90,7 +88,7 @@ export default class TogglablePassword extends React.PureComponent<Props, State>
|
|||
name={name}
|
||||
disabled={disabled}
|
||||
type={isVisible ? 'text' : 'password'}
|
||||
className={`${validity || !isValid ? 'invalid' : ''} border-rad-right-0`}
|
||||
className={`${className} ${!isValid ? 'invalid' : ''} border-rad-right-0`}
|
||||
placeholder={placeholder}
|
||||
onChange={onChange}
|
||||
onFocus={onFocus}
|
||||
|
|
|
@ -71,7 +71,7 @@ const TransactionDataTable: React.SFC<Props> = ({ data, receipt, network }) => {
|
|||
|
||||
const rows: TableRow[] = [
|
||||
{
|
||||
label: 'Status',
|
||||
label: translate('TX_STATUS'),
|
||||
data: (
|
||||
<React.Fragment>
|
||||
<strong className={`TxData-row-data-status is-${statusType}`}>{statusMsg}</strong>
|
||||
|
@ -86,15 +86,15 @@ const TransactionDataTable: React.SFC<Props> = ({ data, receipt, network }) => {
|
|||
)
|
||||
},
|
||||
{
|
||||
label: translate('x_TxHash'),
|
||||
label: translate('X_TXHASH'),
|
||||
data: <MaybeLink href={explorer.tx}>{data.hash}</MaybeLink>
|
||||
},
|
||||
{
|
||||
label: 'Block Number',
|
||||
label: translate('TX_BLOCK_NUMB'),
|
||||
data: receipt && <MaybeLink href={explorer.block}>{receipt.blockNumber}</MaybeLink>
|
||||
},
|
||||
{
|
||||
label: translate('OFFLINE_Step1_Label_1'),
|
||||
label: translate('OFFLINE_STEP1_LABEL_1'),
|
||||
data: (
|
||||
<MaybeLink href={explorer.from}>
|
||||
<Identicon address={data.from} size="26px" />
|
||||
|
@ -103,7 +103,7 @@ const TransactionDataTable: React.SFC<Props> = ({ data, receipt, network }) => {
|
|||
)
|
||||
},
|
||||
{
|
||||
label: translate('OFFLINE_Step2_Label_1'),
|
||||
label: translate('OFFLINE_STEP2_LABEL_1'),
|
||||
data: (
|
||||
<MaybeLink href={explorer.to}>
|
||||
<Identicon address={data.to} size="26px" />
|
||||
|
@ -112,23 +112,23 @@ const TransactionDataTable: React.SFC<Props> = ({ data, receipt, network }) => {
|
|||
)
|
||||
},
|
||||
{
|
||||
label: translate('SEND_amount_short'),
|
||||
label: translate('SEND_AMOUNT_SHORT'),
|
||||
data: <UnitDisplay value={data.value} unit="ether" symbol={network.unit} />
|
||||
},
|
||||
{
|
||||
label: translate('OFFLINE_Step2_Label_3'),
|
||||
label: translate('OFFLINE_STEP2_LABEL_3'),
|
||||
data: <UnitDisplay value={data.gasPrice} unit="gwei" symbol="Gwei" />
|
||||
},
|
||||
{
|
||||
label: translate('OFFLINE_Step2_Label_4'),
|
||||
label: translate('OFFLINE_STEP2_LABEL_4'),
|
||||
data: <UnitDisplay value={data.gas} unit="wei" />
|
||||
},
|
||||
{
|
||||
label: 'Gas Used',
|
||||
label: translate('TX_GAS_USED'),
|
||||
data: receipt && <UnitDisplay value={receipt.gasUsed} unit="wei" />
|
||||
},
|
||||
{
|
||||
label: 'Transaction Fee',
|
||||
label: translate('CONFIRM_TX_FEE'),
|
||||
data: receipt && (
|
||||
<UnitDisplay
|
||||
value={receipt.gasUsed.mul(data.gasPrice)}
|
||||
|
@ -138,7 +138,7 @@ const TransactionDataTable: React.SFC<Props> = ({ data, receipt, network }) => {
|
|||
)
|
||||
},
|
||||
{
|
||||
label: translate('New contract address'),
|
||||
label: translate('NEW_CONTRACT_ADDR'),
|
||||
data: receipt &&
|
||||
receipt.contractAddress && (
|
||||
<MaybeLink href={explorer.contract}>
|
||||
|
@ -147,11 +147,11 @@ const TransactionDataTable: React.SFC<Props> = ({ data, receipt, network }) => {
|
|||
)
|
||||
},
|
||||
{
|
||||
label: translate('OFFLINE_Step2_Label_5'),
|
||||
label: translate('OFFLINE_STEP2_LABEL_5'),
|
||||
data: data.nonce
|
||||
},
|
||||
{
|
||||
label: translate('TRANS_data'),
|
||||
label: translate('TRANS_DATA'),
|
||||
data: hasInputData ? <TextArea value={data.input} disabled={true} /> : null
|
||||
}
|
||||
];
|
||||
|
|
|
@ -44,7 +44,6 @@ class TransactionStatus extends React.Component<Props> {
|
|||
if (tx && tx.data) {
|
||||
content = (
|
||||
<React.Fragment>
|
||||
<h2 className="TxStatus-title">Transaction Found</h2>
|
||||
<div className="TxStatus-data">
|
||||
<TransactionDataTable network={network} data={tx.data} receipt={tx.receipt} />
|
||||
</div>
|
||||
|
@ -53,13 +52,13 @@ class TransactionStatus extends React.Component<Props> {
|
|||
} else if (tx && tx.error) {
|
||||
content = (
|
||||
<div className="TxStatus-error">
|
||||
<h2 className="TxStatus-error-title">{translate('tx_notFound')}</h2>
|
||||
<p className="TxStatus-error-desc">{translate('tx_notFound_1')}</p>
|
||||
<h2 className="TxStatus-error-title">{translate('TX_NOTFOUND')}</h2>
|
||||
<p className="TxStatus-error-desc">{translate('TX_NOTFOUND_1')}</p>
|
||||
<ul className="TxStatus-error-list">
|
||||
<li>Make sure you copied the Transaction Hash correctly</li>
|
||||
<li>{translate('tx_notFound_2')}</li>
|
||||
<li>{translate('tx_notFound_3')}</li>
|
||||
<li>{translate('tx_notFound_4')}</li>
|
||||
<li>{translate('TX_NOTFOUND_5')}</li>
|
||||
<li>{translate('TX_NOTFOUND_2')}</li>
|
||||
<li>{translate('TX_NOTFOUND_3')}</li>
|
||||
<li>{translate('TX_NOTFOUND_4')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
import React from 'react';
|
||||
import Markdown from 'react-markdown';
|
||||
import { translateRaw } from 'translations';
|
||||
|
||||
interface Props {
|
||||
translationKey: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
const Translate = ({ translationKey }: Props) => {
|
||||
const source = translateRaw(translationKey);
|
||||
const TranslateMarkdown = ({ source }: Props) => {
|
||||
return (
|
||||
<Markdown
|
||||
escapeHtml={true}
|
||||
unwrapDisallowed={true}
|
||||
allowedTypes={['link', 'emphasis', 'strong', 'code', 'root', 'inlineCode']}
|
||||
renderers={{ root: 'span' }}
|
||||
renderers={{ root: React.Fragment }}
|
||||
source={source}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Translate;
|
||||
export default TranslateMarkdown;
|
||||
|
|
|
@ -18,7 +18,7 @@ import {
|
|||
TResetWallet
|
||||
} from 'actions/wallet';
|
||||
import { reset, TReset, ResetAction } from 'actions/transaction';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import {
|
||||
KeystoreDecrypt,
|
||||
LedgerNanoSDecrypt,
|
||||
|
@ -50,6 +50,7 @@ import MetamaskIcon from 'assets/images/wallets/metamask.svg';
|
|||
import MistIcon from 'assets/images/wallets/mist.svg';
|
||||
import TrezorIcon from 'assets/images/wallets/trezor.svg';
|
||||
import './WalletDecrypt.scss';
|
||||
import { withRouter, RouteComponentProps } from 'react-router';
|
||||
|
||||
interface OwnProps {
|
||||
hidden?: boolean;
|
||||
|
@ -75,7 +76,7 @@ interface StateProps {
|
|||
isPasswordPending: AppState['wallet']['isPasswordPending'];
|
||||
}
|
||||
|
||||
type Props = OwnProps & StateProps & DispatchProps;
|
||||
type Props = OwnProps & StateProps & DispatchProps & RouteComponentProps<{}>;
|
||||
|
||||
type UnlockParams = {} | PrivateKeyValue;
|
||||
interface State {
|
||||
|
@ -92,6 +93,7 @@ interface BaseWalletInfo {
|
|||
helpLink: string;
|
||||
isReadOnly?: boolean;
|
||||
attemptUnlock?: boolean;
|
||||
redirect?: string;
|
||||
}
|
||||
|
||||
export interface SecureWalletInfo extends BaseWalletInfo {
|
||||
|
@ -108,15 +110,15 @@ interface MiscWalletInfo extends InsecureWalletInfo {}
|
|||
|
||||
const WEB3_TYPES = {
|
||||
CipherProvider: {
|
||||
lid: 'x_Cipher',
|
||||
lid: 'X_CIPHER',
|
||||
icon: CipherIcon
|
||||
},
|
||||
MetamaskInpageProvider: {
|
||||
lid: 'x_MetaMask',
|
||||
lid: 'X_METAMASK',
|
||||
icon: MetamaskIcon
|
||||
},
|
||||
EthereumProvider: {
|
||||
lid: 'x_Mist',
|
||||
lid: 'X_MIST',
|
||||
icon: MistIcon
|
||||
}
|
||||
};
|
||||
|
@ -133,311 +135,319 @@ const SECURE_WALLETS = Object.values(SecureWalletName);
|
|||
const INSECURE_WALLETS = Object.values(InsecureWalletName);
|
||||
const MISC_WALLETS = Object.values(MiscWalletName);
|
||||
|
||||
export class WalletDecrypt extends Component<Props, State> {
|
||||
// https://github.com/Microsoft/TypeScript/issues/13042
|
||||
// index signature should become [key: Wallets] (from config) once typescript bug is fixed
|
||||
public WALLETS: Wallets = {
|
||||
[SecureWalletName.WEB3]: {
|
||||
lid: WEB3_TYPE && WEB3_TYPES[WEB3_TYPE] ? WEB3_TYPES[WEB3_TYPE].lid : 'x_Web3',
|
||||
icon: WEB3_TYPE && WEB3_TYPES[WEB3_TYPE] && WEB3_TYPES[WEB3_TYPE].icon,
|
||||
description: 'ADD_Web3Desc',
|
||||
component: Web3Decrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockWeb3,
|
||||
attemptUnlock: true,
|
||||
helpLink: `${knowledgeBaseURL}/migration/moving-from-private-key-to-metamask`
|
||||
},
|
||||
[SecureWalletName.LEDGER_NANO_S]: {
|
||||
lid: 'x_Ledger',
|
||||
icon: LedgerIcon,
|
||||
description: 'ADD_HardwareDesc',
|
||||
component: LedgerNanoSDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://support.ledgerwallet.com/hc/en-us/articles/115005200009'
|
||||
},
|
||||
[SecureWalletName.TREZOR]: {
|
||||
lid: 'x_Trezor',
|
||||
icon: TrezorIcon,
|
||||
description: 'ADD_HardwareDesc',
|
||||
component: TrezorDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://doc.satoshilabs.com/trezor-apps/mew.html'
|
||||
},
|
||||
[InsecureWalletName.KEYSTORE_FILE]: {
|
||||
lid: 'x_Keystore2',
|
||||
example: 'UTC--2017-12-15T17-35-22.547Z--6be6e49e82425a5aa56396db03512f2cc10e95e8',
|
||||
component: KeystoreDecrypt,
|
||||
initialParams: {
|
||||
file: '',
|
||||
password: ''
|
||||
const WalletDecrypt = withRouter<Props>(
|
||||
class WalletDecryptClass extends Component<RouteComponentProps<{}> & Props, State> {
|
||||
// https://github.com/Microsoft/TypeScript/issues/13042
|
||||
// index signature should become [key: Wallets] (from config) once typescript bug is fixed
|
||||
public WALLETS: Wallets = {
|
||||
[SecureWalletName.WEB3]: {
|
||||
lid: WEB3_TYPE && WEB3_TYPES[WEB3_TYPE] ? WEB3_TYPES[WEB3_TYPE].lid : 'X_WEB3',
|
||||
icon: WEB3_TYPE && WEB3_TYPES[WEB3_TYPE] && WEB3_TYPES[WEB3_TYPE].icon,
|
||||
description: 'ADD_WEB3DESC',
|
||||
component: Web3Decrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockWeb3,
|
||||
attemptUnlock: true,
|
||||
helpLink: `${knowledgeBaseURL}/migration/moving-from-private-key-to-metamask`
|
||||
},
|
||||
unlock: this.props.unlockKeystore,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
[InsecureWalletName.MNEMONIC_PHRASE]: {
|
||||
lid: 'x_Mnemonic',
|
||||
example: 'brain surround have swap horror cheese file distinct',
|
||||
component: MnemonicDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockMnemonic,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
[InsecureWalletName.PRIVATE_KEY]: {
|
||||
lid: 'x_PrivKey2',
|
||||
example: 'f1d0e0789c6d40f399ca90cc674b7858de4c719e0d5752a60d5d2f6baa45d4c9',
|
||||
component: PrivateKeyDecrypt,
|
||||
initialParams: {
|
||||
key: '',
|
||||
password: ''
|
||||
[SecureWalletName.LEDGER_NANO_S]: {
|
||||
lid: 'X_LEDGER',
|
||||
icon: LedgerIcon,
|
||||
description: 'ADD_HARDWAREDESC',
|
||||
component: LedgerNanoSDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://support.ledgerwallet.com/hc/en-us/articles/115005200009'
|
||||
},
|
||||
unlock: this.props.unlockPrivateKey,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
[MiscWalletName.VIEW_ONLY]: {
|
||||
lid: 'View Address',
|
||||
example: donationAddressMap.ETH,
|
||||
component: ViewOnlyDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: '',
|
||||
isReadOnly: true
|
||||
}
|
||||
};
|
||||
[SecureWalletName.TREZOR]: {
|
||||
lid: 'X_TREZOR',
|
||||
icon: TrezorIcon,
|
||||
description: 'ADD_HARDWAREDESC',
|
||||
component: TrezorDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://doc.satoshilabs.com/trezor-apps/mew.html'
|
||||
},
|
||||
[InsecureWalletName.KEYSTORE_FILE]: {
|
||||
lid: 'X_KEYSTORE2',
|
||||
example: 'UTC--2017-12-15T17-35-22.547Z--6be6e49e82425a5aa56396db03512f2cc10e95e8',
|
||||
component: KeystoreDecrypt,
|
||||
initialParams: {
|
||||
file: '',
|
||||
password: ''
|
||||
},
|
||||
unlock: this.props.unlockKeystore,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
[InsecureWalletName.MNEMONIC_PHRASE]: {
|
||||
lid: 'X_MNEMONIC',
|
||||
example: 'brain surround have swap horror cheese file distinct',
|
||||
component: MnemonicDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockMnemonic,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
[InsecureWalletName.PRIVATE_KEY]: {
|
||||
lid: 'X_PRIVKEY2',
|
||||
example: 'f1d0e0789c6d40f399ca90cc674b7858de4c719e0d5752a60d5d2f6baa45d4c9',
|
||||
component: PrivateKeyDecrypt,
|
||||
initialParams: {
|
||||
key: '',
|
||||
password: ''
|
||||
},
|
||||
unlock: this.props.unlockPrivateKey,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
[MiscWalletName.VIEW_ONLY]: {
|
||||
lid: 'VIEW_ADDR',
|
||||
example: donationAddressMap.ETH,
|
||||
component: ViewOnlyDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: '',
|
||||
isReadOnly: true,
|
||||
redirect: '/account/info'
|
||||
}
|
||||
};
|
||||
|
||||
public state: State = {
|
||||
selectedWalletKey: null,
|
||||
value: null,
|
||||
hasAcknowledgedInsecure: false
|
||||
};
|
||||
public state: State = {
|
||||
selectedWalletKey: null,
|
||||
value: null,
|
||||
hasAcknowledgedInsecure: false
|
||||
};
|
||||
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
// Reset state when unlock is hidden / revealed
|
||||
if (nextProps.hidden !== this.props.hidden) {
|
||||
this.setState({
|
||||
value: null,
|
||||
selectedWalletKey: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public getSelectedWallet() {
|
||||
const { selectedWalletKey } = this.state;
|
||||
if (!selectedWalletKey) {
|
||||
return null;
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
// Reset state when unlock is hidden / revealed
|
||||
if (nextProps.hidden !== this.props.hidden) {
|
||||
this.setState({
|
||||
value: null,
|
||||
selectedWalletKey: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this.WALLETS[selectedWalletKey];
|
||||
}
|
||||
public getSelectedWallet() {
|
||||
const { selectedWalletKey } = this.state;
|
||||
if (!selectedWalletKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public getDecryptionComponent() {
|
||||
const { selectedWalletKey, hasAcknowledgedInsecure } = this.state;
|
||||
const selectedWallet = this.getSelectedWallet();
|
||||
if (!selectedWalletKey || !selectedWallet) {
|
||||
return null;
|
||||
return this.WALLETS[selectedWalletKey];
|
||||
}
|
||||
|
||||
if (INSECURE_WALLETS.includes(selectedWalletKey) && !hasAcknowledgedInsecure) {
|
||||
public getDecryptionComponent() {
|
||||
const { selectedWalletKey, hasAcknowledgedInsecure } = this.state;
|
||||
const selectedWallet = this.getSelectedWallet();
|
||||
if (!selectedWalletKey || !selectedWallet) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (INSECURE_WALLETS.includes(selectedWalletKey) && !hasAcknowledgedInsecure) {
|
||||
return (
|
||||
<div className="WalletDecrypt-decrypt">
|
||||
<InsecureWalletWarning
|
||||
walletType={translate(selectedWallet.lid)}
|
||||
onContinue={this.handleAcknowledgeInsecure}
|
||||
onCancel={this.clearWalletChoice}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="WalletDecrypt-decrypt">
|
||||
<InsecureWalletWarning
|
||||
walletType={translate(selectedWallet.lid)}
|
||||
onContinue={this.handleAcknowledgeInsecure}
|
||||
onCancel={this.clearWalletChoice}
|
||||
/>
|
||||
<button className="WalletDecrypt-decrypt-back" onClick={this.clearWalletChoice}>
|
||||
<i className="fa fa-arrow-left" /> {translate('CHANGE_WALLET')}
|
||||
</button>
|
||||
<h2 className="WalletDecrypt-decrypt-title">
|
||||
{!selectedWallet.isReadOnly && 'Unlock your'} {translate(selectedWallet.lid)}
|
||||
</h2>
|
||||
<section className="WalletDecrypt-decrypt-form">
|
||||
<selectedWallet.component
|
||||
value={this.state.value}
|
||||
onChange={this.onChange}
|
||||
onUnlock={(value: any) => {
|
||||
if (selectedWallet.redirect) {
|
||||
this.props.history.push(selectedWallet.redirect);
|
||||
}
|
||||
this.onUnlock(value);
|
||||
}}
|
||||
showNotification={this.props.showNotification}
|
||||
isWalletPending={
|
||||
this.state.selectedWalletKey === InsecureWalletName.KEYSTORE_FILE
|
||||
? this.props.isWalletPending
|
||||
: undefined
|
||||
}
|
||||
isPasswordPending={
|
||||
this.state.selectedWalletKey === InsecureWalletName.KEYSTORE_FILE
|
||||
? this.props.isPasswordPending
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="WalletDecrypt-decrypt">
|
||||
<button className="WalletDecrypt-decrypt-back" onClick={this.clearWalletChoice}>
|
||||
<i className="fa fa-arrow-left" /> {translate('Change Wallet')}
|
||||
</button>
|
||||
<h2 className="WalletDecrypt-decrypt-title">
|
||||
{!selectedWallet.isReadOnly && 'Unlock your'} {translate(selectedWallet.lid)}
|
||||
</h2>
|
||||
<section className="WalletDecrypt-decrypt-form">
|
||||
<selectedWallet.component
|
||||
value={this.state.value}
|
||||
onChange={this.onChange}
|
||||
onUnlock={this.onUnlock}
|
||||
showNotification={this.props.showNotification}
|
||||
isWalletPending={
|
||||
this.state.selectedWalletKey === InsecureWalletName.KEYSTORE_FILE
|
||||
? this.props.isWalletPending
|
||||
: undefined
|
||||
}
|
||||
isPasswordPending={
|
||||
this.state.selectedWalletKey === InsecureWalletName.KEYSTORE_FILE
|
||||
? this.props.isPasswordPending
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
public handleAcknowledgeInsecure = () => {
|
||||
this.setState({ hasAcknowledgedInsecure: true });
|
||||
};
|
||||
|
||||
public handleAcknowledgeInsecure = () => {
|
||||
this.setState({ hasAcknowledgedInsecure: true });
|
||||
};
|
||||
public buildWalletOptions() {
|
||||
const { computedDisabledWallets } = this.props;
|
||||
const { reasons } = computedDisabledWallets;
|
||||
|
||||
public buildWalletOptions() {
|
||||
const { computedDisabledWallets } = this.props;
|
||||
const { reasons } = computedDisabledWallets;
|
||||
return (
|
||||
<div className="WalletDecrypt-wallets">
|
||||
<h2 className="WalletDecrypt-wallets-title">{translate('DECRYPT_ACCESS')}</h2>
|
||||
|
||||
return (
|
||||
<div className="WalletDecrypt-wallets">
|
||||
<h2 className="WalletDecrypt-wallets-title">{translate('decrypt_Access')}</h2>
|
||||
|
||||
<div className="WalletDecrypt-wallets-row">
|
||||
{SECURE_WALLETS.map((walletType: SecureWalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
return (
|
||||
<WalletButton
|
||||
key={walletType}
|
||||
name={translate(wallet.lid)}
|
||||
description={translate(wallet.description)}
|
||||
icon={wallet.icon}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={walletType}
|
||||
isSecure={true}
|
||||
isDisabled={this.isWalletDisabled(walletType)}
|
||||
disableReason={reasons[walletType]}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="WalletDecrypt-wallets-row">
|
||||
{INSECURE_WALLETS.map((walletType: InsecureWalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
return (
|
||||
<WalletButton
|
||||
key={walletType}
|
||||
name={translate(wallet.lid)}
|
||||
example={wallet.example}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={walletType}
|
||||
isSecure={false}
|
||||
isDisabled={this.isWalletDisabled(walletType)}
|
||||
disableReason={reasons[walletType]}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
{MISC_WALLETS.map((walletType: MiscWalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
return (
|
||||
<WalletButton
|
||||
key={walletType}
|
||||
name={translate(wallet.lid)}
|
||||
example={wallet.example}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={walletType}
|
||||
isReadOnly={true}
|
||||
isDisabled={this.isWalletDisabled(walletType)}
|
||||
disableReason={reasons[walletType]}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{this.props.showGenerateLink && (
|
||||
<div className="WalletDecrypt-wallets-generate">
|
||||
Don’t have an account yet? <Link to="/generate">Click here to get one</Link>.
|
||||
<div className="WalletDecrypt-wallets-row">
|
||||
{SECURE_WALLETS.map((walletType: SecureWalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
return (
|
||||
<WalletButton
|
||||
key={walletType}
|
||||
name={translateRaw(wallet.lid)}
|
||||
description={translateRaw(wallet.description)}
|
||||
icon={wallet.icon}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={walletType}
|
||||
isSecure={true}
|
||||
isDisabled={this.isWalletDisabled(walletType)}
|
||||
disableReason={reasons[walletType]}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
<div className="WalletDecrypt-wallets-row">
|
||||
{INSECURE_WALLETS.map((walletType: InsecureWalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
return (
|
||||
<WalletButton
|
||||
key={walletType}
|
||||
name={translateRaw(wallet.lid)}
|
||||
example={wallet.example}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={walletType}
|
||||
isSecure={false}
|
||||
isDisabled={this.isWalletDisabled(walletType)}
|
||||
disableReason={reasons[walletType]}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
public handleWalletChoice = async (walletType: WalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
{MISC_WALLETS.map((walletType: MiscWalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
return (
|
||||
<WalletButton
|
||||
key={walletType}
|
||||
name={translateRaw(wallet.lid)}
|
||||
example={wallet.example}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={walletType}
|
||||
isReadOnly={true}
|
||||
isDisabled={this.isWalletDisabled(walletType)}
|
||||
disableReason={reasons[walletType]}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
if (!wallet) {
|
||||
return;
|
||||
{this.props.showGenerateLink && (
|
||||
<div className="WalletDecrypt-wallets-generate">
|
||||
<Link to="/generate">{translate('DONT_HAVE_WALLET_PROMPT')}</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let timeout = 0;
|
||||
const web3Available = await isWeb3NodeAvailable();
|
||||
if (wallet.attemptUnlock && web3Available) {
|
||||
// timeout is only the maximum wait time before secondary view is shown
|
||||
// send view will be shown immediately on web3 resolve
|
||||
timeout = 1000;
|
||||
wallet.unlock();
|
||||
}
|
||||
public handleWalletChoice = async (walletType: WalletName) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (!wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
let timeout = 0;
|
||||
const web3Available = await isWeb3NodeAvailable();
|
||||
if (wallet.attemptUnlock && web3Available) {
|
||||
// timeout is only the maximum wait time before secondary view is shown
|
||||
// send view will be shown immediately on web3 resolve
|
||||
timeout = 1000;
|
||||
wallet.unlock();
|
||||
}
|
||||
|
||||
window.setTimeout(() => {
|
||||
this.setState({
|
||||
selectedWalletKey: walletType,
|
||||
value: wallet.initialParams,
|
||||
hasAcknowledgedInsecure: false
|
||||
});
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
public clearWalletChoice = () => {
|
||||
this.setState({
|
||||
selectedWalletKey: walletType,
|
||||
value: wallet.initialParams,
|
||||
selectedWalletKey: null,
|
||||
value: null,
|
||||
hasAcknowledgedInsecure: false
|
||||
});
|
||||
}, timeout);
|
||||
};
|
||||
};
|
||||
|
||||
public clearWalletChoice = () => {
|
||||
this.setState({
|
||||
selectedWalletKey: null,
|
||||
value: null,
|
||||
hasAcknowledgedInsecure: false
|
||||
});
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { hidden } = this.props;
|
||||
const selectedWallet = this.getSelectedWallet();
|
||||
const decryptionComponent = this.getDecryptionComponent();
|
||||
return (
|
||||
<div>
|
||||
{!hidden && (
|
||||
<article className="Tab-content-pane">
|
||||
<div className="WalletDecrypt">
|
||||
<TransitionGroup>
|
||||
{decryptionComponent && selectedWallet ? (
|
||||
<CSSTransition classNames="DecryptContent" timeout={500} key="decrypt">
|
||||
{decryptionComponent}
|
||||
</CSSTransition>
|
||||
) : (
|
||||
<CSSTransition classNames="DecryptContent" timeout={500} key="wallets">
|
||||
{this.buildWalletOptions()}
|
||||
</CSSTransition>
|
||||
)}
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public onChange = (value: UnlockParams) => {
|
||||
this.setState({ value });
|
||||
};
|
||||
|
||||
public onUnlock = (payload: any) => {
|
||||
const { value, selectedWalletKey } = this.state;
|
||||
if (!selectedWalletKey) {
|
||||
return;
|
||||
public render() {
|
||||
const { hidden } = this.props;
|
||||
const selectedWallet = this.getSelectedWallet();
|
||||
const decryptionComponent = this.getDecryptionComponent();
|
||||
return (
|
||||
<div>
|
||||
{!hidden && (
|
||||
<article className="Tab-content-pane">
|
||||
<div className="WalletDecrypt">
|
||||
<TransitionGroup>
|
||||
{decryptionComponent && selectedWallet ? (
|
||||
<CSSTransition classNames="DecryptContent" timeout={500} key="decrypt">
|
||||
{decryptionComponent}
|
||||
</CSSTransition>
|
||||
) : (
|
||||
<CSSTransition classNames="DecryptContent" timeout={500} key="wallets">
|
||||
{this.buildWalletOptions()}
|
||||
</CSSTransition>
|
||||
)}
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// some components (TrezorDecrypt) don't take an onChange prop, and thus
|
||||
// this.state.value will remain unpopulated. in this case, we can expect
|
||||
// the payload to contain the unlocked wallet info.
|
||||
const unlockValue = value && !isEmpty(value) ? value : payload;
|
||||
this.WALLETS[selectedWalletKey].unlock(unlockValue);
|
||||
this.props.resetTransactionState(this.props.resetIncludeExcludeProperties);
|
||||
};
|
||||
public onChange = (value: UnlockParams) => {
|
||||
this.setState({ value });
|
||||
};
|
||||
|
||||
private isWalletDisabled = (walletKey: WalletName) => {
|
||||
return this.props.computedDisabledWallets.wallets.indexOf(walletKey) !== -1;
|
||||
};
|
||||
}
|
||||
public onUnlock = (payload: any) => {
|
||||
const { value, selectedWalletKey } = this.state;
|
||||
if (!selectedWalletKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
// some components (TrezorDecrypt) don't take an onChange prop, and thus
|
||||
// this.state.value will remain unpopulated. in this case, we can expect
|
||||
// the payload to contain the unlocked wallet info.
|
||||
const unlockValue = value && !isEmpty(value) ? value : payload;
|
||||
this.WALLETS[selectedWalletKey].unlock(unlockValue);
|
||||
this.props.resetTransactionState(this.props.resetIncludeExcludeProperties);
|
||||
};
|
||||
|
||||
private isWalletDisabled = (walletKey: WalletName) => {
|
||||
return this.props.computedDisabledWallets.wallets.indexOf(walletKey) !== -1;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
function mapStateToProps(state: AppState, ownProps: Props) {
|
||||
const { disabledWallets } = ownProps;
|
||||
|
@ -460,7 +470,7 @@ function mapStateToProps(state: AppState, ownProps: Props) {
|
|||
};
|
||||
}
|
||||
|
||||
export default connect<StateProps, DispatchProps>(mapStateToProps, {
|
||||
export default connect(mapStateToProps, {
|
||||
unlockKeystore,
|
||||
unlockMnemonic,
|
||||
unlockPrivateKey,
|
||||
|
@ -469,4 +479,4 @@ export default connect<StateProps, DispatchProps>(mapStateToProps, {
|
|||
resetWallet,
|
||||
resetTransactionState: reset,
|
||||
showNotification
|
||||
})(WalletDecrypt);
|
||||
})(WalletDecrypt) as React.ComponentClass<OwnProps>;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import Select, { Option } from 'react-select';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import {
|
||||
DeterministicWalletData,
|
||||
getDeterministicWallets,
|
||||
|
@ -101,13 +101,13 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
|||
|
||||
const buttons: IButton[] = [
|
||||
{
|
||||
text: 'Unlock this Address',
|
||||
text: translate('ACTION_3'),
|
||||
type: 'primary',
|
||||
onClick: this.handleConfirmAddress,
|
||||
disabled: !selectedAddress
|
||||
},
|
||||
{
|
||||
text: 'Cancel',
|
||||
text: translate('ACTION_2'),
|
||||
type: 'default',
|
||||
onClick: onCancel
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
|||
|
||||
return (
|
||||
<Modal
|
||||
title={`Unlock your ${walletType || ''} Wallet`}
|
||||
title={translateRaw(`DECRYPT_PROMPT_UNLOCK_${walletType}`)}
|
||||
isOpen={this.props.isOpen}
|
||||
buttons={buttons}
|
||||
handleClose={onCancel}
|
||||
|
@ -125,7 +125,7 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
|||
className="DWModal-path form-group-sm flex-wrapper"
|
||||
onSubmit={this.handleSubmitCustomPath}
|
||||
>
|
||||
<span className="DWModal-path-label">Addresses </span>
|
||||
<span className="DWModal-path-label">{translate('DECRYPT_DROPDOWN_LABEL')} </span>
|
||||
<div className="DWModal-path-select">
|
||||
<Select
|
||||
name="fieldDPath"
|
||||
|
@ -180,7 +180,7 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
|||
))}
|
||||
</select>
|
||||
</td>
|
||||
<td>More</td>
|
||||
<td>{translate('ACTION_5')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{wallets.map(wallet => this.renderWalletRow(wallet))}</tbody>
|
||||
|
@ -192,13 +192,13 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
|||
disabled={page === 0}
|
||||
onClick={this.prevPage}
|
||||
>
|
||||
← Back
|
||||
← {translate('ACTION_4')}
|
||||
</button>
|
||||
<button
|
||||
className="DWModal-addresses-nav-btn btn btn-sm btn-default"
|
||||
onClick={this.nextPage}
|
||||
>
|
||||
More →
|
||||
{translate('ACTION_5')} →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import { HelpLink } from 'components/ui';
|
||||
import { HELP_ARTICLE } from 'config';
|
||||
import './InsecureWalletWarning.scss';
|
||||
import translate from 'translations';
|
||||
import { knowledgeBaseURL } from 'config/data';
|
||||
|
||||
interface Props {
|
||||
walletType: string | React.ReactElement<string>;
|
||||
|
@ -43,15 +44,15 @@ export class InsecureWalletWarning extends React.Component<Props, State> {
|
|||
const checkboxes: Checkbox[] = [
|
||||
{
|
||||
name: 'hasAcknowledgedWallets',
|
||||
label: 'I acknowledge that I can and should use MetaMask or a Hardware Wallet'
|
||||
label: translate('INSECURE_WALLET_WARNING_1')
|
||||
},
|
||||
{
|
||||
name: 'hasAcknowledgedDownload',
|
||||
label: 'I acknowledge that I can and should download and run MyCrypto locally'
|
||||
label: translate('INSECURE_WALLET_WARNING_2')
|
||||
},
|
||||
{
|
||||
name: 'hasConfirmedSite',
|
||||
label: 'I have checked the URL and SSL certificate to make sure this is the real MyCrypto'
|
||||
label: translate('INSECURE_WALLET_WARNING_3')
|
||||
}
|
||||
];
|
||||
const canContinue = checkboxes.reduce(
|
||||
|
@ -61,38 +62,31 @@ export class InsecureWalletWarning extends React.Component<Props, State> {
|
|||
|
||||
return (
|
||||
<div className="WalletWarning">
|
||||
<h2 className="WalletWarning-title">
|
||||
This is <u>not</u> a recommended way to access your wallet
|
||||
</h2>
|
||||
<h2 className="WalletWarning-title">{translate('INSECURE_WALLET_TYPE_TITLE')}</h2>
|
||||
<p className="WalletWarning-desc">
|
||||
Entering your {walletType} on a website is <strong>dangerous</strong>. If our website is
|
||||
compromised, or you accidentally visit a phishing website, you could{' '}
|
||||
<strong>lose all of your funds</strong>. Before you continue, please consider:
|
||||
{translate('INSECURE_WALLET_TYPE_DESC', { $wallet_type: walletType as string })}
|
||||
</p>
|
||||
<ul className="WalletWarning-bullets">
|
||||
<li>
|
||||
Using <HelpLink article={HELP_ARTICLE.MIGRATE_TO_METAMASK}>MetaMask</HelpLink> or a{' '}
|
||||
<HelpLink article={HELP_ARTICLE.HARDWARE_WALLET_RECOMMENDATIONS}>
|
||||
Hardware Wallet
|
||||
</HelpLink>{' '}
|
||||
to access your wallet
|
||||
{translate('INSECURE_WALLET_RECOMMEND_1', {
|
||||
$metamask_article: knowledgeBaseURL + '/' + HELP_ARTICLE.MIGRATE_TO_METAMASK,
|
||||
$hardware_wallet_article:
|
||||
knowledgeBaseURL + '/' + HELP_ARTICLE.HARDWARE_WALLET_RECOMMENDATIONS
|
||||
})}
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.RUNNING_LOCALLY}>
|
||||
Downloading MyCrypto and running it offline & locally
|
||||
</HelpLink>
|
||||
{translate('INSECURE_WALLET_RECOMMEND_2', {
|
||||
$run_local_article: knowledgeBaseURL + '/' + HELP_ARTICLE.RUNNING_LOCALLY
|
||||
})}
|
||||
</li>
|
||||
<li>
|
||||
Reading{' '}
|
||||
<HelpLink article={HELP_ARTICLE.SECURING_YOUR_ETH}>
|
||||
How to Protect Yourself and Your Funds
|
||||
</HelpLink>
|
||||
{translate('INSECURE_WALLET_RECOMMEND_3', {
|
||||
$secure_your_eth_article: knowledgeBaseURL + '/' + HELP_ARTICLE.SECURING_YOUR_ETH
|
||||
})}
|
||||
</li>
|
||||
</ul>
|
||||
<p className="WalletWarning-check">
|
||||
If you must use your {walletType} online, please double-check the URL & SSL certificate.
|
||||
It should say <code>{'https://www.mycrypto.com'}</code>
|
||||
& <code>MyCrypto, Inc (US)</code> in your URL bar.
|
||||
{translate('WALLET_WARNING_CHECK', { $wallet_type: walletType as string })}
|
||||
</p>
|
||||
<div className="WalletWarning-checkboxes">{checkboxes.map(this.makeCheckbox)}</div>
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ export class KeystoreDecrypt extends PureComponent {
|
|||
/>
|
||||
<label htmlFor="fselector" style={{ width: '100%' }}>
|
||||
<a className="btn btn-default btn-block" id="aria1" tabIndex={0} role="button">
|
||||
{translate('ADD_Radio_2_short')}
|
||||
{translate('ADD_RADIO_2_SHORT')}
|
||||
</a>
|
||||
</label>
|
||||
{isWalletPending ? <Spinner /> : ''}
|
||||
|
@ -63,13 +63,13 @@ export class KeystoreDecrypt extends PureComponent {
|
|||
value={password}
|
||||
onChange={this.onPasswordChange}
|
||||
onKeyDown={this.onKeyDown}
|
||||
placeholder={translateRaw('x_Password')}
|
||||
placeholder={translateRaw('INPUT_PASSWORD_LABEL')}
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button className="btn btn-primary btn-block" disabled={unlockDisabled}>
|
||||
{translate('ADD_Label_6_short')}
|
||||
{translate('ADD_LABEL_6_SHORT')}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import './LedgerNano.scss';
|
||||
import React, { PureComponent } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import translate from 'translations';
|
||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||
import { LedgerWallet } from 'libs/wallet';
|
||||
import ledger from 'ledgerco';
|
||||
|
@ -83,23 +83,22 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
|
|||
{isLoading ? (
|
||||
<div className="LedgerDecrypt-message">
|
||||
<Spinner light={true} />
|
||||
Unlocking...
|
||||
{translate('WALLET_UNLOCKING')}
|
||||
</div>
|
||||
) : (
|
||||
translate('ADD_Ledger_scan')
|
||||
translate('ADD_LEDGER_SCAN')
|
||||
)}
|
||||
</button>
|
||||
|
||||
<NewTabLink className="LedgerDecrypt-buy btn btn-sm btn-default" href={ledgerReferralURL}>
|
||||
{translate('Don’t have a Ledger? Order one now!')}
|
||||
{translate('LEDGER_REFERAL_2')}
|
||||
</NewTabLink>
|
||||
|
||||
<div className={`LedgerDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||
|
||||
<div className="LedgerDecrypt-help">
|
||||
Guide:{' '}
|
||||
<NewTabLink href="https://support.ledgerwallet.com/hc/en-us/articles/115005200009">
|
||||
How to use MyCrypto with your Nano S
|
||||
{translate('HELP_ARTICLE_1')}
|
||||
</NewTabLink>
|
||||
</div>
|
||||
|
||||
|
@ -112,7 +111,7 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
|
|||
onCancel={this.handleCancel}
|
||||
onConfirmAddress={this.handleUnlock}
|
||||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Ledger')}
|
||||
walletType={'LEDGER'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -55,7 +55,7 @@ class MnemonicDecryptClass extends PureComponent<Props, State> {
|
|||
<TogglablePassword
|
||||
value={phrase}
|
||||
rows={4}
|
||||
placeholder={translateRaw('x_Mnemonic')}
|
||||
placeholder={translateRaw('X_MNEMONIC')}
|
||||
isValid={isValidMnemonic}
|
||||
isTextareaWhenVisible={true}
|
||||
onChange={this.onMnemonicChange}
|
||||
|
@ -63,11 +63,11 @@ class MnemonicDecryptClass extends PureComponent<Props, State> {
|
|||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<p>Password (optional):</p>
|
||||
<p>{translate('ADD_LABEL_8')}</p>
|
||||
<Input
|
||||
value={pass}
|
||||
onChange={this.onPasswordChange}
|
||||
placeholder={translateRaw('x_Password')}
|
||||
placeholder={translateRaw('INPUT_PASSWORD_LABEL')}
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
|
@ -78,7 +78,7 @@ class MnemonicDecryptClass extends PureComponent<Props, State> {
|
|||
className="btn btn-primary btn-lg"
|
||||
disabled={!isValidMnemonic}
|
||||
>
|
||||
{translate('Choose Address')}
|
||||
{translate('MNEMONIC_CHOOSE_ADDR')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -91,7 +91,7 @@ class MnemonicDecryptClass extends PureComponent<Props, State> {
|
|||
onCancel={this.handleCancel}
|
||||
onConfirmAddress={this.handleUnlock}
|
||||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Mnemonic')}
|
||||
walletType={'MNEMONIC'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -59,7 +59,7 @@ export class PrivateKeyDecrypt extends PureComponent<Props> {
|
|||
<TogglablePassword
|
||||
value={key}
|
||||
rows={4}
|
||||
placeholder={translateRaw('x_PrivKey2')}
|
||||
placeholder={translateRaw('X_PRIVKEY2')}
|
||||
isValid={isValidPkey}
|
||||
onChange={this.onPkeyChange}
|
||||
onEnter={this.props.onUnlock}
|
||||
|
@ -70,20 +70,20 @@ export class PrivateKeyDecrypt extends PureComponent<Props> {
|
|||
isPassRequired && (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('ADD_Label_3')}</div>
|
||||
<div className="input-group-header">{translate('ADD_LABEL_3')}</div>
|
||||
<Input
|
||||
className={`form-control ${password.length > 0 ? 'is-valid' : 'is-invalid'}`}
|
||||
value={password}
|
||||
onChange={this.onPasswordChange}
|
||||
onKeyDown={this.onKeyDown}
|
||||
placeholder={translateRaw('x_Password')}
|
||||
placeholder={translateRaw('INPUT_PASSWORD_LABEL')}
|
||||
type="password"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
<button className="btn btn-block btn-primary" disabled={unlockDisabled}>
|
||||
{translate('ADD_Label_6_short')}
|
||||
{translate('ADD_LABEL_6_SHORT')}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { TrezorWallet, TREZOR_MINIMUM_FIRMWARE } from 'libs/wallet';
|
||||
import React, { PureComponent } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import translate from 'translations';
|
||||
import TrezorConnect from 'vendor/trezor-connect';
|
||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||
import './Trezor.scss';
|
||||
|
@ -63,7 +63,7 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
|
|||
Unlocking...
|
||||
</div>
|
||||
) : (
|
||||
translate('ADD_Trezor_scan')
|
||||
translate('ADD_TREZOR_SCAN')
|
||||
)}
|
||||
</button>
|
||||
|
||||
|
@ -74,7 +74,6 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
|
|||
<div className={`TrezorDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||
|
||||
<div className="TrezorDecrypt-help">
|
||||
Guide:{' '}
|
||||
<NewTabLink href="https://blog.trezor.io/trezor-integration-with-myetherwallet-3e217a652e08">
|
||||
How to use TREZOR with MyCrypto
|
||||
</NewTabLink>
|
||||
|
@ -89,7 +88,7 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
|
|||
onCancel={this.handleCancel}
|
||||
onConfirmAddress={this.handleUnlock}
|
||||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Trezor')}
|
||||
walletType={'TREZOR'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -35,7 +35,7 @@ export class ViewOnlyDecrypt extends PureComponent<Props, State> {
|
|||
/>
|
||||
|
||||
<button className="btn btn-primary btn-block" disabled={!isValid}>
|
||||
{translate('NAV_ViewWallet')}
|
||||
{translate('NAV_VIEWWALLET')}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { translateRaw, TranslateType } from 'translations';
|
||||
import { NewTabLink, Tooltip } from 'components/ui';
|
||||
import './WalletButton.scss';
|
||||
|
||||
import { WalletName } from 'config';
|
||||
import { translateRaw } from 'translations';
|
||||
|
||||
interface OwnProps {
|
||||
name: TranslateType;
|
||||
description?: TranslateType;
|
||||
example?: TranslateType;
|
||||
name: string;
|
||||
description?: string;
|
||||
example?: string;
|
||||
icon?: string;
|
||||
helpLink: string;
|
||||
walletType: WalletName;
|
||||
|
@ -51,20 +51,20 @@ export class WalletButton extends React.PureComponent<Props> {
|
|||
if (isReadOnly) {
|
||||
icons.push({
|
||||
icon: 'eye',
|
||||
tooltip: translateRaw('You cannot send using address only'),
|
||||
tooltip: translateRaw('TOOLTIP_READ_ONLY_WALLET'),
|
||||
arialabel: 'Read Only'
|
||||
});
|
||||
} else {
|
||||
if (isSecure) {
|
||||
icons.push({
|
||||
icon: 'shield',
|
||||
tooltip: translateRaw('This wallet type is secure'),
|
||||
tooltip: translateRaw('TOOLTIP_SECURE_WALLET_TYPE'),
|
||||
arialabel: 'Secure wallet type'
|
||||
});
|
||||
} else {
|
||||
icons.push({
|
||||
icon: 'exclamation-triangle',
|
||||
tooltip: translateRaw('This wallet type is insecure'),
|
||||
tooltip: translateRaw('TOOLTIP_INSECURE_WALLET_TYPE'),
|
||||
arialabel: 'Insecure wallet type'
|
||||
});
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ export class WalletButton extends React.PureComponent<Props> {
|
|||
if (helpLink) {
|
||||
icons.push({
|
||||
icon: 'question-circle',
|
||||
tooltip: translateRaw('NAV_Help'),
|
||||
tooltip: translateRaw('TOOLTIP_MORE_INFO'),
|
||||
href: helpLink,
|
||||
arialabel: 'More info'
|
||||
});
|
||||
|
|
|
@ -11,14 +11,14 @@ export const Web3Decrypt: React.SFC<Props> = ({ onUnlock }) => (
|
|||
<div className="Web3Decrypt">
|
||||
<div>
|
||||
<button className="Web3Decrypt-decrypt btn btn-primary btn-lg btn-block" onClick={onUnlock}>
|
||||
{translate('ADD_MetaMask')}
|
||||
{translate('ADD_METAMASK')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<NewTabLink
|
||||
className="Web3Decrypt-install btn btn-sm btn-default btn-block"
|
||||
content={translate('Download MetaMask')}
|
||||
content={translate('ACTION_13', { $thing: 'MetaMask' })}
|
||||
href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ type ButtonType = 'default' | 'primary' | 'success' | 'info' | 'warning' | 'dang
|
|||
type ButtonSize = 'lg' | 'sm' | 'xs';
|
||||
|
||||
interface Props {
|
||||
text: React.ReactElement<any> | string;
|
||||
text: string;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
loadingText?: string;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import translate, { TranslateType } from 'translations';
|
||||
import translate from 'translations';
|
||||
import WalletDecrypt, { DisabledWallets } from 'components/WalletDecrypt';
|
||||
import { IWallet } from 'libs/wallet/IWallet';
|
||||
import closeIcon from 'assets/images/close.svg';
|
||||
import './UnlockHeader.scss';
|
||||
|
||||
interface Props {
|
||||
title: TranslateType;
|
||||
title: string;
|
||||
wallet: IWallet;
|
||||
disabledWallets?: DisabledWallets;
|
||||
showGenerateLink?: boolean;
|
||||
|
@ -44,7 +44,7 @@ export class UnlockHeader extends React.PureComponent<Props, State> {
|
|||
>
|
||||
<span>
|
||||
<span className="hidden-xs UnlockHeader-open-text">
|
||||
{translate('Change Wallet')}
|
||||
{translate('CHANGE_WALLET')}
|
||||
</span>
|
||||
<i className="fa fa-refresh" />
|
||||
</span>
|
||||
|
|
|
@ -4,15 +4,15 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconFour from 'assets/images/onboarding/slide-04.svg';
|
||||
|
||||
const BlockchainSlide = () => {
|
||||
const header = translate('ONBOARD_blockchain_title');
|
||||
const header = translate('ONBOARD_BLOCKCHAIN_TITLE');
|
||||
const content = (
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_blockchain_content__1')}</li>
|
||||
<li>{translate('ONBOARD_blockchain_content__2')}</li>
|
||||
<li>{translate('ONBOARD_blockchain_content__3')}</li>
|
||||
<li>{translate('ONBOARD_blockchain_content__4')}</li>
|
||||
<li>{translate('ONBOARD_blockchain_content__5')}</li>
|
||||
<li>{translate('ONBOARD_blockchain_content__6')}</li>
|
||||
<li>{translate('ONBOARD_BLOCKCHAIN_CONTENT__1')}</li>
|
||||
<li>{translate('ONBOARD_BLOCKCHAIN_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_BLOCKCHAIN_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_BLOCKCHAIN_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_BLOCKCHAIN_CONTENT__5')}</li>
|
||||
<li>{translate('ONBOARD_BLOCKCHAIN_CONTENT__6')}</li>
|
||||
</ul>
|
||||
);
|
||||
return (
|
||||
|
|
|
@ -11,49 +11,49 @@ interface Props {
|
|||
}
|
||||
|
||||
const FinalSlide: React.SFC<Props> = ({ closeModal }) => {
|
||||
const header = translate('ONBOARD_final_title');
|
||||
const subheader = translate('ONBOARD_final_subtitle');
|
||||
const header = translate('ONBOARD_FINAL_TITLE');
|
||||
const subheader = translate('ONBOARD_FINAL_SUBTITLE');
|
||||
|
||||
const content = (
|
||||
<ul>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.HARDWARE_WALLET_RECOMMENDATIONS} className="strong">
|
||||
{translate('ONBOARD_final_content__2')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__2')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.MIGRATE_TO_METAMASK} className="strong">
|
||||
{translate('ONBOARD_final_content__3')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__3')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.RUNNING_LOCALLY} className="strong">
|
||||
{translate('ONBOARD_final_content__4')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__4')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.MIGRATE_TO_LEDGER} className="strong">
|
||||
{translate('ONBOARD_final_content__5')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__5')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.SENDING_TO_TREZOR} className="strong">
|
||||
{translate('ONBOARD_final_content__6')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__6')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.MIGRATE_TO_METAMASK} className="strong">
|
||||
{translate('ONBOARD_final_content__7')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__7')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<HelpLink article={HELP_ARTICLE.HOME} className="strong">
|
||||
{translate('ONBOARD_final_content__8')}
|
||||
{translate('ONBOARD_FINAL_CONTENT__8')}
|
||||
</HelpLink>
|
||||
</li>
|
||||
<li>
|
||||
<Link onClick={closeModal} to="/account" className="strong">
|
||||
<span> {translate('ONBOARD_final_content__9')}</span>
|
||||
<span> {translate('ONBOARD_FINAL_CONTENT__9')}</span>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -4,17 +4,17 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconThree from 'assets/images/onboarding/slide-03.svg';
|
||||
|
||||
const InterfaceSlide = () => {
|
||||
const header = translate('ONBOARD_interface_title');
|
||||
const header = translate('ONBOARD_INTERFACE_TITLE');
|
||||
|
||||
const content = (
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_interface_content__1')}</li>
|
||||
<li>{translate('ONBOARD_interface_content__2')}</li>
|
||||
<li>{translate('ONBOARD_interface_content__3')}</li>
|
||||
<li>{translate('ONBOARD_interface_content__4')}</li>
|
||||
<li>{translate('ONBOARD_interface_content__5')}</li>
|
||||
<li>{translate('ONBOARD_interface_content__6')}</li>
|
||||
<li>{translate('ONBOARD_interface_content__7')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__1')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__5')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__6')}</li>
|
||||
<li>{translate('ONBOARD_INTERFACE_CONTENT__7')}</li>
|
||||
</ul>
|
||||
);
|
||||
return (
|
||||
|
|
|
@ -4,15 +4,15 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconTwo from 'assets/images/onboarding/slide-02.svg';
|
||||
|
||||
const NotABankSlide = () => {
|
||||
const header = translate('ONBOARD_bank_title');
|
||||
const header = translate('ONBOARD_BANK_TITLE');
|
||||
|
||||
const content = (
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_bank_content__1')}</li>
|
||||
<li>{translate('ONBOARD_bank_content__2')}</li>
|
||||
<li>{translate('ONBOARD_bank_content__3')}</li>
|
||||
<li>{translate('ONBOARD_bank_content__4')}</li>
|
||||
<li>{translate('ONBOARD_bank_content__5')}</li>
|
||||
<li>{translate('ONBOARD_BANK_CONTENT__1')}</li>
|
||||
<li>{translate('ONBOARD_BANK_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_BANK_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_BANK_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_BANK_CONTENT__5')}</li>
|
||||
</ul>
|
||||
);
|
||||
|
||||
|
|
|
@ -4,18 +4,18 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconSeven from 'assets/images/onboarding/slide-07.svg';
|
||||
|
||||
const SecureSlideOne = () => {
|
||||
const header = translate('ONBOARD_secure_1_title');
|
||||
const header = translate('ONBOARD_SECURE_1_TITLE');
|
||||
|
||||
const content = (
|
||||
<div>
|
||||
<p>{translate('ONBOARD_secure_1_content__1')}</p>
|
||||
<p>{translate('ONBOARD_SECURE_1_CONTENT__1')}</p>
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_secure_1_content__2')}</li>
|
||||
<li>{translate('ONBOARD_secure_1_content__3')} </li>
|
||||
<li>{translate('ONBOARD_secure_1_content__4')}</li>
|
||||
<li>{translate('ONBOARD_secure_1_content__5')}</li>
|
||||
<li>{translate('ONBOARD_secure_1_content__6')}</li>
|
||||
<li>{translate('ONBOARD_secure_1_content__7')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_1_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_1_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_1_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_1_CONTENT__5')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_1_CONTENT__6')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_1_CONTENT__7')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -8,19 +8,19 @@ interface Props {
|
|||
}
|
||||
|
||||
const SecureSlideThree: React.SFC<Props> = ({ site }) => {
|
||||
const header = translate('ONBOARD_secure_3_title');
|
||||
const subheader = translate('ONBOARD_secure_3_content__1');
|
||||
const header = translate('ONBOARD_SECURE_3_TITLE');
|
||||
const subheader = translate('ONBOARD_SECURE_3_CONTENT__1');
|
||||
|
||||
const content = (
|
||||
<div>
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_secure_3_content__2')}</li>
|
||||
<li>{translate('ONBOARD_secure_3_content__3')}</li>
|
||||
<li>{translate('ONBOARD_secure_3_content__4')}</li>
|
||||
<li>{translate('ONBOARD_secure_3_content__5')}</li>
|
||||
{site === 'cx' && <li>{translate('CX_Warning_1')}</li>}
|
||||
<li>{translate('ONBOARD_SECURE_3_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_3_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_3_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_3_CONTENT__5')}</li>
|
||||
{site === 'cx' && <li>{translate('CX_WARNING_1')}</li>}
|
||||
</ul>
|
||||
<h5 className="text-center">{translate('ONBOARD_secure_3_content__6')} </h5>
|
||||
<h5 className="text-center">{translate('ONBOARD_SECURE_3_CONTENT__6')} </h5>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconEight from 'assets/images/onboarding/slide-08.svg';
|
||||
|
||||
const SecureSlideTwo = () => {
|
||||
const header = translate('ONBOARD_secure_2_title');
|
||||
const subheader = translate('ONBOARD_secure_2_content__1');
|
||||
const header = translate('ONBOARD_SECURE_2_TITLE');
|
||||
const subheader = translate('ONBOARD_SECURE_2_CONTENT__1');
|
||||
|
||||
const content = (
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_secure_2_content__2')}</li>
|
||||
<li>{translate('ONBOARD_secure_2_content__3')}</li>
|
||||
<li>{translate('ONBOARD_secure_2_content__4')}</li>
|
||||
<li>{translate('ONBOARD_secure_2_content__5')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_2_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_2_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_2_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_SECURE_2_CONTENT__5')}</li>
|
||||
</ul>
|
||||
);
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import onboardIconOne from 'assets/images/onboarding/slide-01.svg';
|
|||
import './WelcomeSlide.scss';
|
||||
|
||||
const WelcomeSlide = () => {
|
||||
const header = translate('ONBOARD_welcome_title');
|
||||
const subheader = <small>{translate('ONBOARD_welcome_content__3')}</small>;
|
||||
const header = translate('ONBOARD_WELCOME_TITLE');
|
||||
const subheader = <small>{translate('ONBOARD_WELCOME_CONTENT__3')}</small>;
|
||||
|
||||
const content = (
|
||||
<div>
|
||||
|
@ -16,21 +16,21 @@ const WelcomeSlide = () => {
|
|||
<i className="fa fa-exclamation-triangle" />
|
||||
</div>
|
||||
<span>
|
||||
{translate('ONBOARD_welcome_content__1')}
|
||||
{translate('ONBOARD_welcome_content__2')}
|
||||
{translate('ONBOARD_WELCOME_CONTENT__1')}
|
||||
{translate('ONBOARD_WELCOME_CONTENT__2')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="WelcomeSlide-alert">
|
||||
<div className="WelcomeSlide-alert-icon">
|
||||
<i className="fa fa-exclamation-triangle" />
|
||||
</div>
|
||||
<span>{translate('ONBOARD_welcome_content__8')}</span>
|
||||
{translate('ONBOARD_WELCOME_CONTENT__8')}
|
||||
</div>
|
||||
<h5>{translate('ONBOARD_welcome_content__4')}</h5>
|
||||
<h5>{translate('ONBOARD_WELCOME_CONTENT__4')}</h5>
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_welcome_content__5')}</li>
|
||||
<li>{translate('ONBOARD_welcome_content__6')}</li>
|
||||
<li>{translate('ONBOARD_welcome_content__7')}</li>
|
||||
<li>{translate('ONBOARD_WELCOME_CONTENT__5')}</li>
|
||||
<li>{translate('ONBOARD_WELCOME_CONTENT__6')}</li>
|
||||
<li>{translate('ONBOARD_WELCOME_CONTENT__7')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -4,16 +4,16 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconSix from 'assets/images/onboarding/slide-06.svg';
|
||||
|
||||
const WhyMewSlide = () => {
|
||||
const header = translate('ONBOARD_whymyc_title');
|
||||
const header = translate('ONBOARD_WHYMYC_TITLE');
|
||||
|
||||
const content = (
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_whymyc_content__1')}</li>
|
||||
<li>{translate('ONBOARD_whymyc_content__2')}</li>
|
||||
<li>{translate('ONBOARD_whymyc_content__3')}</li>
|
||||
<li>{translate('ONBOARD_whymyc_content__4')}</li>
|
||||
<li>{translate('ONBOARD_whymyc_content__5')}</li>
|
||||
<li>{translate('ONBOARD_whymyc_content__6')}</li>
|
||||
<li>{translate('ONBOARD_WHYMYC_CONTENT__1')}</li>
|
||||
<li>{translate('ONBOARD_WHYMYC_CONTENT__2')}</li>
|
||||
<li>{translate('ONBOARD_WHYMYC_CONTENT__3')}</li>
|
||||
<li>{translate('ONBOARD_WHYMYC_CONTENT__4')}</li>
|
||||
<li>{translate('ONBOARD_WHYMYC_CONTENT__5')}</li>
|
||||
<li>{translate('ONBOARD_WHYMYC_CONTENT__6')}</li>
|
||||
</ul>
|
||||
);
|
||||
return <OnboardSlide header={header} content={content} image={onboardIconSix} imageSide="left" />;
|
||||
|
|
|
@ -4,23 +4,23 @@ import OnboardSlide from './OnboardSlide';
|
|||
import onboardIconFive from 'assets/images/onboarding/slide-05.svg';
|
||||
|
||||
const WhySlide = () => {
|
||||
const header = translate('ONBOARD_why_title');
|
||||
const header = translate('ONBOARD_WHY_TITLE');
|
||||
|
||||
const content = (
|
||||
<div>
|
||||
<h5>{translate('ONBOARD_why_content__1')}</h5>
|
||||
<h5>{translate('ONBOARD_WHY_CONTENT__1')}</h5>
|
||||
<ul>
|
||||
<li className="text-danger">{translate('ONBOARD_why_content__2')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_why_content__3')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_why_content__4')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_why_content__5')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_why_content__6')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_WHY_CONTENT__2')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_WHY_CONTENT__3')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_WHY_CONTENT__4')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_WHY_CONTENT__5')}</li>
|
||||
<li className="text-danger">{translate('ONBOARD_WHY_CONTENT__6')}</li>
|
||||
</ul>
|
||||
<h5>{translate('ONBOARD_why_content__7')}</h5>
|
||||
<h5>{translate('ONBOARD_WHY_CONTENT__7')}</h5>
|
||||
<ul>
|
||||
<li>{translate('ONBOARD_why_content__8')}</li>
|
||||
<li>{translate('ONBOARD_why_content__9')}</li>
|
||||
<li>{translate('ONBOARD_why_content__10')}</li>
|
||||
<li>{translate('ONBOARD_WHY_CONTENT__8')}</li>
|
||||
<li>{translate('ONBOARD_WHY_CONTENT__9')}</li>
|
||||
<li>{translate('ONBOARD_WHY_CONTENT__10')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -74,7 +74,7 @@ class OnboardModal extends React.Component<Props, State> {
|
|||
isOpen: true
|
||||
});
|
||||
|
||||
const onboardResumeMessage = translate('ONBOARD_resume');
|
||||
const onboardResumeMessage = translate('ONBOARD_RESUME');
|
||||
|
||||
// Wait a sec so it doesn't get lost in the page-load
|
||||
setTimeout(() => {
|
||||
|
@ -91,25 +91,25 @@ class OnboardModal extends React.Component<Props, State> {
|
|||
const firstButtons: IButton[] = [
|
||||
{
|
||||
disabled: slideNumber === NUMBER_OF_SLIDES,
|
||||
text: 'Next',
|
||||
text: translate('ACTION_6'),
|
||||
type: 'primary',
|
||||
onClick: this.handleNextSlide
|
||||
},
|
||||
{
|
||||
disabled: slideNumber === 1,
|
||||
text: 'Back',
|
||||
text: translate('ACTION_4'),
|
||||
type: 'default',
|
||||
onClick: this.handlePreviousSlide
|
||||
}
|
||||
];
|
||||
const lastButtons: IButton[] = [
|
||||
{
|
||||
text: 'Finish',
|
||||
text: translate('ACTION_10'),
|
||||
type: 'primary',
|
||||
onClick: this.closeModal
|
||||
},
|
||||
{
|
||||
text: 'Back',
|
||||
text: translate('ACTION_4'),
|
||||
type: 'default',
|
||||
onClick: this.handlePreviousSlide
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import TabSection from 'containers/TabSection';
|
||||
import { translateRaw } from 'translations';
|
||||
import translate from 'translations';
|
||||
import {
|
||||
signLocalTransactionSucceeded,
|
||||
TSignLocalTransactionSucceeded,
|
||||
|
@ -49,14 +49,12 @@ class BroadcastTx extends Component<Props> {
|
|||
path={currentPath}
|
||||
render={() => (
|
||||
<div className="BroadcastTx">
|
||||
<h1 className="BroadcastTx-title">Broadcast Signed Transaction</h1>
|
||||
<p className="BroadcastTx-help">
|
||||
Paste a signed transaction and press the "SEND TRANSACTION" button.
|
||||
</p>
|
||||
<h1 className="BroadcastTx-title">{translate('BROADCAST_TX_TITLE')}</h1>
|
||||
<p className="BroadcastTx-help">{translate('BROADCAST_TX_DESCRIPTION')}</p>
|
||||
|
||||
<div className="input-group-wrapper InteractForm-interface">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translateRaw('SEND_signed')}</div>
|
||||
<div className="input-group-header">{translate('SEND_SIGNED')}</div>
|
||||
<TextArea
|
||||
className={stateTransaction ? '' : 'invalid'}
|
||||
rows={7}
|
||||
|
|
|
@ -66,10 +66,10 @@ class TxHashInput extends React.Component<Props, State> {
|
|||
value={hash}
|
||||
onChange={this.handleSelectTx}
|
||||
options={selectOptions}
|
||||
placeholder="Select a recent transaction..."
|
||||
placeholder={translate('SELECT_RECENT_TX')}
|
||||
searchable={false}
|
||||
/>
|
||||
<em className="TxHashInput-recent-separator">or</em>
|
||||
<em className="TxHashInput-recent-separator">{translate('OR')}</em>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
@ -82,12 +82,12 @@ class TxHashInput extends React.Component<Props, State> {
|
|||
|
||||
{isValidETHAddress(hash) && (
|
||||
<p className="TxHashInput-message help-block is-invalid">
|
||||
You cannot use an address, you must use a transaction hash
|
||||
{translate('SELECT_RECENT_TX_BY_TXHASH')}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<button className="TxHashInput-submit btn btn-primary btn-block">
|
||||
{translate('NAV_CheckTxStatus')}
|
||||
{translate('NAV_CHECKTXSTATUS')}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -4,12 +4,12 @@ import { RouteComponentProps } from 'react-router';
|
|||
import TabSection from 'containers/TabSection';
|
||||
import TxHashInput from './components/TxHashInput';
|
||||
import { TransactionStatus as TransactionStatusComponent } from 'components';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import { getParamFromURL } from 'utils/helpers';
|
||||
import { AppState } from 'reducers';
|
||||
import { NetworkConfig } from 'types/network';
|
||||
import './index.scss';
|
||||
import translate from 'translations';
|
||||
|
||||
interface StateProps {
|
||||
network: NetworkConfig;
|
||||
|
@ -48,18 +48,14 @@ class CheckTransaction extends React.Component<Props, State> {
|
|||
<TabSection>
|
||||
<div className="CheckTransaction Tab-content">
|
||||
<section className="CheckTransaction-form Tab-content-pane">
|
||||
<h1 className="CheckTransaction-form-title">Check Transaction Status</h1>
|
||||
<h1 className="CheckTransaction-form-title">{translate('CHECK_TX_STATUS_TITLE')}</h1>
|
||||
<p className="CheckTransaction-form-desc">
|
||||
Enter your Transaction Hash to check on its status.{' '}
|
||||
{!network.isCustom && (
|
||||
<React.Fragment>
|
||||
If you don’t know your Transaction Hash, you can look it up on the{' '}
|
||||
<NewTabLink href={network.blockExplorer.origin}>
|
||||
{network.blockExplorer.name} explorer
|
||||
</NewTabLink>{' '}
|
||||
by looking up your address.
|
||||
</React.Fragment>
|
||||
)}
|
||||
{translate('CHECK_TX_STATUS_DESCRIPTION_1')}
|
||||
{!network.isCustom &&
|
||||
translate('CHECK_TX_STATUS_DESCRIPTION_2', {
|
||||
$block_explorer: network.blockExplorer.name,
|
||||
$block_explorer_link: network.blockExplorer.origin
|
||||
})}
|
||||
</p>
|
||||
<TxHashInput hash={hash} onSubmit={this.handleHashSubmit} />
|
||||
</section>
|
||||
|
|
|
@ -26,12 +26,12 @@ class DeployClass extends Component<DispatchProps> {
|
|||
<main className="Deploy Tab-content-pane" role="main">
|
||||
<button className="Deploy-field-reset btn btn-default btn-sm" onClick={this.changeWallet}>
|
||||
<i className="fa fa-refresh" />
|
||||
{translate('Change Wallet')}
|
||||
{translate('CHANGE_WALLET')}
|
||||
</button>
|
||||
|
||||
<div className="input-group-wrapper Deploy-field">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('CONTRACT_ByteCode')}</div>
|
||||
<div className="input-group-header">{translate('CONTRACT_BYTECODE')}</div>
|
||||
<DataFieldFactory
|
||||
withProps={({ data: { raw, value }, onChange, readOnly }) => (
|
||||
<TextArea
|
||||
|
@ -76,7 +76,7 @@ class DeployClass extends Component<DispatchProps> {
|
|||
Modal={ConfirmationModal}
|
||||
withProps={({ onClick }) => (
|
||||
<button className="Deploy-submit btn btn-primary" onClick={onClick}>
|
||||
{translate('NAV_DeployContract')}
|
||||
{translate('NAV_DEPLOYCONTRACT')}
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -78,7 +78,7 @@ class InteractExplorerClass extends Component<Props, State> {
|
|||
className="InteractExplorer-func-submit btn btn-primary"
|
||||
onClick={this.handleFunctionSend}
|
||||
>
|
||||
{translate('CONTRACT_Write')}
|
||||
{translate('CONTRACT_WRITE')}
|
||||
</button>
|
||||
);
|
||||
|
||||
|
@ -87,14 +87,14 @@ class InteractExplorerClass extends Component<Props, State> {
|
|||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">
|
||||
{translate('CONTRACT_Interact_Title')}
|
||||
{translate('CONTRACT_INTERACT_TITLE')}
|
||||
<div className="flex-spacer" />
|
||||
<span className="small">{to.raw}</span>
|
||||
</div>
|
||||
<Dropdown
|
||||
name="exploreContract"
|
||||
value={selectedFunction as any}
|
||||
placeholder="Please select a function..."
|
||||
placeholder={translate('SELECT_A_THING', { $thing: 'function' })}
|
||||
onChange={this.handleFunctionSelect}
|
||||
options={contractFunctionsOptions}
|
||||
clearable={false}
|
||||
|
@ -147,7 +147,7 @@ class InteractExplorerClass extends Component<Props, State> {
|
|||
className="InteractExplorer-func-submit btn btn-primary"
|
||||
onClick={this.handleFunctionCall}
|
||||
>
|
||||
{translate('CONTRACT_Read')}
|
||||
{translate('CONTRACT_READ')}
|
||||
</button>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from 'react';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { getNetworkContracts } from 'selectors/config';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
|
@ -52,8 +52,8 @@ class InteractForm extends Component<Props, State> {
|
|||
abiJson: '',
|
||||
contract: null,
|
||||
contractPlaceholder: this.isContractsValid()
|
||||
? 'Please select a contract...'
|
||||
: 'No contracts available'
|
||||
? translateRaw('SELECT_A_THING', { $thing: 'contract' })
|
||||
: translateRaw('NO_CONTRACTS_AVAILABLE')
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ class InteractForm extends Component<Props, State> {
|
|||
<div className="InteractForm-address row">
|
||||
<div className="input-group-wrapper InteractForm-address-field col-sm-6">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('CONTRACT_Title')}</div>
|
||||
<div className="input-group-header">{translate('CONTRACT_TITLE')}</div>
|
||||
<Input
|
||||
placeholder={`ensdomain.eth or ${donationAddressMap.ETH}`}
|
||||
name="contract_address"
|
||||
|
@ -102,7 +102,7 @@ class InteractForm extends Component<Props, State> {
|
|||
|
||||
<div className="input-group-wrapper InteractForm-address-field col-sm-6">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('CONTRACT_Title_2')}</div>
|
||||
<div className="input-group-header">{translate('CONTRACT_TITLE_2')}</div>
|
||||
<Dropdown
|
||||
className={`${!contract ? 'invalid' : ''}`}
|
||||
value={contract as any}
|
||||
|
@ -118,7 +118,7 @@ class InteractForm extends Component<Props, State> {
|
|||
|
||||
<div className="input-group-wrapper InteractForm-interface">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('CONTRACT_Json')}</div>
|
||||
<div className="input-group-header">{translate('CONTRACT_JSON')}</div>
|
||||
<TextArea
|
||||
placeholder={this.abiJsonPlaceholder}
|
||||
className={`InteractForm-interface-field-input ${validAbiJson ? '' : 'invalid'}`}
|
||||
|
@ -134,7 +134,7 @@ class InteractForm extends Component<Props, State> {
|
|||
disabled={!showContractAccessButton}
|
||||
onClick={accessContract(abiJson, address)}
|
||||
>
|
||||
{translate('x_Access')}
|
||||
{translate('X_ACCESS')}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -18,11 +18,11 @@ interface Props {
|
|||
const tabs = [
|
||||
{
|
||||
path: 'interact',
|
||||
name: translate('Interact')
|
||||
name: translate('CONTRACTS_INTERACT')
|
||||
},
|
||||
{
|
||||
path: 'deploy',
|
||||
name: translate('Deploy')
|
||||
name: translate('CONTRACTS_DEPLOY')
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { resolveDomainRequested, TResolveDomainRequested } from 'actions/ens';
|
|||
import { isValidENSName } from 'libs/validators';
|
||||
import './NameInput.scss';
|
||||
import { Input } from 'components/ui';
|
||||
import translate from 'translations';
|
||||
|
||||
interface State {
|
||||
domainToCheck: string;
|
||||
|
@ -26,7 +27,7 @@ class NameInput extends Component<Props, State> {
|
|||
|
||||
public render() {
|
||||
const { domainRequests } = this.props;
|
||||
const { isValidDomain, domainToCheck, isFocused } = this.state;
|
||||
const { isValidDomain, domainToCheck } = this.state;
|
||||
const req = domainRequests[domainToCheck];
|
||||
const isLoading = req && !req.data && !req.error;
|
||||
|
||||
|
@ -48,19 +49,16 @@ class NameInput extends Component<Props, State> {
|
|||
/>
|
||||
<span className="input-group-addon">.eth</span>
|
||||
</label>
|
||||
{domainToCheck &&
|
||||
!isValidDomain && (
|
||||
<p className="help-block is-invalid">{translate('ENS_INVALID_INPUT')}</p>
|
||||
)}
|
||||
</div>
|
||||
{domainToCheck &&
|
||||
!isValidDomain &&
|
||||
!isFocused && (
|
||||
<p className="help-block is-invalid">
|
||||
Must be at least 7 characters, no special characters
|
||||
</p>
|
||||
)}
|
||||
<button
|
||||
className="ENSInput-button btn btn-primary btn-block"
|
||||
disabled={!isValidDomain || isLoading}
|
||||
>
|
||||
Check Availability
|
||||
{translate('ACTION_9')}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -4,6 +4,7 @@ import ENSTime from './components/ENSTime';
|
|||
import moment from 'moment';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import { ensV3Url } from 'utils/formatters';
|
||||
import translate from 'translations';
|
||||
|
||||
const getDeadlines = (registrationDate: string) => {
|
||||
// Get the time to reveal bids, and the time when the action closes
|
||||
|
@ -20,9 +21,7 @@ export const NameAuction: React.SFC<IBaseDomainRequest> = props => {
|
|||
<section className="row">
|
||||
<div className="auction-info text-center">
|
||||
<div className="ens-title">
|
||||
<h1>
|
||||
An auction has started for <strong>{name}.eth</strong>
|
||||
</h1>
|
||||
<h1>{translate('ENS_DOMAIN_AUCTION', { $name: name + '.eth' })}</h1>
|
||||
</div>
|
||||
|
||||
<div className="ens-panel-wrapper">
|
||||
|
@ -35,11 +34,9 @@ export const NameAuction: React.SFC<IBaseDomainRequest> = props => {
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Do you want to place a bid on {name}.eth?{' '}
|
||||
{translate('NAME_AUCTION_PROMPT_BID')}
|
||||
<strong>
|
||||
<NewTabLink href={ensV3Url(name)}>
|
||||
You can do that on MyCrypto V3 by clicking here!
|
||||
</NewTabLink>
|
||||
<NewTabLink href={ensV3Url(name)}>{translate('NAME_AUCTION_PROMPT_BID_2')}</NewTabLink>
|
||||
</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { IBaseDomainRequest } from 'libs/ens';
|
||||
import translate from 'translations';
|
||||
|
||||
export const NameForbidden: React.SFC<IBaseDomainRequest> = props => (
|
||||
<h1>{props.name}.eth is forbidden</h1>
|
||||
<h1>{translate('ENS_DOMAIN_FORBIDDEN', { $name: props.name + '.eth' })}</h1>
|
||||
);
|
||||
|
|
|
@ -2,21 +2,19 @@ import React from 'react';
|
|||
import { IBaseDomainRequest } from 'libs/ens';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import { ensV3Url } from 'utils/formatters';
|
||||
import translate from 'translations';
|
||||
|
||||
export const NameOpen: React.SFC<IBaseDomainRequest> = props => (
|
||||
<section className="row">
|
||||
<section className="auction-info text-center">
|
||||
<div className="ens-title">
|
||||
<h1>
|
||||
<strong>{props.name}.eth</strong> is available
|
||||
</h1>
|
||||
<h1>{translate('ENS_DOMAIN_OPEN', { $name: props.name + '.eth' })}</h1>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Do you want {props.name}.eth?{' '}
|
||||
{translate('OPEN_AUCTION_PROMPT_1', { $name: props.name })}
|
||||
<strong>
|
||||
<NewTabLink className="text-center" href={ensV3Url(props.name)}>
|
||||
Open an auction on MyCrypto v3!
|
||||
{translate('OPEN_AUCTION_PROMPT_2')}
|
||||
</NewTabLink>
|
||||
</strong>
|
||||
</p>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { IOwnedDomainRequest } from 'libs/ens';
|
||||
import { NewTabLink, Address } from 'components/ui';
|
||||
import translate from 'translations';
|
||||
const lookupLink = (name: string) => `https://etherscan.io/enslookup?q=${name}`;
|
||||
|
||||
type ChildrenProps = any;
|
||||
|
@ -17,41 +18,39 @@ export const NameOwned: React.SFC<IOwnedDomainRequest> = ({
|
|||
}) => (
|
||||
<section>
|
||||
<div className="ens-title">
|
||||
<h1 className="text-center">
|
||||
<strong>{name}.eth</strong> is already owned
|
||||
</h1>
|
||||
<h1 className="text-center">{translate('ENS_DOMAIN_OWNED', { $name: name + '.eth' })}</h1>
|
||||
</div>
|
||||
<div className="ens-table-wrapper">
|
||||
<table className="table table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Name: </td>
|
||||
<td>{translate('NAME_OWNED_NAME')}:</td>
|
||||
<MonoTd>
|
||||
<NewTabLink content={`${name}.eth`} href={lookupLink(`${name}.eth`)} />
|
||||
</MonoTd>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Labelhash ({name}): </td>
|
||||
<td>{translate('NAME_OWNED_LABELHASH', { name })}:</td>
|
||||
<MonoTd>{labelHash}</MonoTd>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Namehash ({name}.eth): </td>
|
||||
<td>{translate('NAME_OWNED_NAMEHASH', { name })} </td>
|
||||
<MonoTd>{nameHash}</MonoTd>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Owner:</td>
|
||||
<td>{translate('NAME_OWNED_OWNER')}:</td>
|
||||
<MonoTd>
|
||||
<Address address={ownerAddress} />
|
||||
</MonoTd>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Highest Bidder (Deed Owner): </td>
|
||||
<td>{translate('NAME_OWNED_HIGHEST_BIDDER')}</td>
|
||||
<MonoTd>
|
||||
<span>{highestBid}</span>
|
||||
</MonoTd>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Resolved Address: </td>
|
||||
<td>{translate('NAME_OWNED_RESOLVED_ADDR')}:</td>
|
||||
<MonoTd>
|
||||
<Address address={resolvedAddress} />
|
||||
</MonoTd>
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import React from 'react';
|
||||
import { IRevealDomainRequest } from 'libs/ens';
|
||||
import ENSTime from './components/ENSTime';
|
||||
import { UnitDisplay, NewTabLink } from 'components/ui';
|
||||
import { UnitDisplay } from 'components/ui';
|
||||
import { Wei } from 'libs/units';
|
||||
import { ensV3Url } from 'utils/formatters';
|
||||
import translate from 'translations';
|
||||
|
||||
export const NameReveal: React.SFC<IRevealDomainRequest> = props => (
|
||||
<section className="row text-center">
|
||||
<div className="auction-info text-center">
|
||||
<div className="ens-title">
|
||||
<h2>
|
||||
It's time to reveal the bids for <strong>{props.name}.eth</strong>
|
||||
{translate('ENS_DOMAIN_REVEAL', { $name: props.name + '.eth' })}
|
||||
<br />
|
||||
The current highest bid is{' '}
|
||||
{translate('ENS_DOMAIN_HIGHEST_BID')}
|
||||
<strong>
|
||||
<UnitDisplay
|
||||
value={Wei(props.highestBid)}
|
||||
|
@ -33,12 +34,10 @@ export const NameReveal: React.SFC<IRevealDomainRequest> = props => (
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Did you bid on {props.name}.eth? You must reveal your bid now.{' '}
|
||||
<strong>
|
||||
<NewTabLink href={ensV3Url(props.name)}>
|
||||
You can do that on MyCrypto v3 by clicking here!
|
||||
</NewTabLink>
|
||||
</strong>
|
||||
{translate('ENS_DOMAIN_PROMPT_REVEAL', {
|
||||
$name: props.name + '.eth',
|
||||
$link: ensV3Url(props.name)
|
||||
})}
|
||||
</p>
|
||||
</section>
|
||||
);
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import React from 'react';
|
||||
import { NameInput, NameResolve } from './components';
|
||||
import TabSection from 'containers/TabSection';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import { donationAddressMap } from 'config';
|
||||
import './index.scss';
|
||||
|
||||
const ENSDocsLink = () => (
|
||||
<NewTabLink
|
||||
href="https://ens.readthedocs.io/en/latest/introduction.html"
|
||||
content="Ethereum Name Service"
|
||||
/>
|
||||
);
|
||||
import translate from 'translations';
|
||||
|
||||
export default class ENSClass extends React.Component<{}> {
|
||||
public render() {
|
||||
|
@ -21,16 +14,14 @@ export default class ENSClass extends React.Component<{}> {
|
|||
<div className="ENS">
|
||||
<h1 className="ENS-title">Ethereum Name Service</h1>
|
||||
<p className="ENS-description">
|
||||
The <ENSDocsLink /> is a distributed, open, and extensible naming system based on
|
||||
the Ethereum blockchain. Once you have a name, you can tell your friends to send ETH
|
||||
to <code>ensdomain.eth</code> instead of
|
||||
<code>{donationAddressMap.ETH.substr(0, 12)}...</code>
|
||||
{translate('ENS_DESCRIPTION', {
|
||||
$ens_docs: 'https://ens.readthedocs.io/en/latest/introduction.html',
|
||||
$example_donation_addr: donationAddressMap.ETH.substr(0, 8)
|
||||
})}
|
||||
</p>
|
||||
|
||||
<NameInput />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<NameResolve />
|
||||
</div>
|
||||
</TabSection>
|
||||
|
|
|
@ -17,45 +17,42 @@ interface Props {
|
|||
const FinalSteps: React.SFC<Props> = ({ walletType }) => {
|
||||
const steps = [
|
||||
{
|
||||
name: 'Open MyCrypto',
|
||||
name: translate('MNEMONIC_FINAL_STEP_1'),
|
||||
image: SiteImage
|
||||
},
|
||||
{
|
||||
name: 'Go to the account tab',
|
||||
name: translate('MNEMONIC_FINAL_STEP_2'),
|
||||
image: TabImage
|
||||
}
|
||||
];
|
||||
|
||||
if (walletType === WalletType.Keystore) {
|
||||
steps.push({
|
||||
name: 'Select your wallet type',
|
||||
name: translate('MNEMONIC_FINAL_STEP_3'),
|
||||
image: SelectKeystoreImage
|
||||
});
|
||||
steps.push({
|
||||
name: 'Provide file & password',
|
||||
name: translate('MNEMONIC_FINAL_STEP_5'),
|
||||
image: ProvideKeystoreImage
|
||||
});
|
||||
} else if (walletType === WalletType.Mnemonic) {
|
||||
steps.push({
|
||||
name: 'Select your wallet type',
|
||||
name: translate('MNEMONIC_FINAL_STEP_3'),
|
||||
image: SelectMnemonicImage
|
||||
});
|
||||
steps.push({
|
||||
name: 'Enter your phrase',
|
||||
name: translate('MNEMONIC_FINAL_STEP_4'),
|
||||
image: ProvideMnemonicImage
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="FinalSteps">
|
||||
<h1 className="FinalSteps-title">{translate('ADD_Label_6')}</h1>
|
||||
<p className="FinalSteps-help">
|
||||
All done, you’re now ready to access your wallet. Just follow these 4 steps whenever you
|
||||
want to access your wallet.
|
||||
</p>
|
||||
<h1 className="FinalSteps-title">{translate('ADD_LABEL_6')}</h1>
|
||||
<p className="FinalSteps-help">{translate('MNEMONIC_FINAL_DESCRIPTION')}</p>
|
||||
<div className="FinalSteps-steps row">
|
||||
{steps.map((step, index) => (
|
||||
<div key={step.name} className="StepBox col-lg-3 col-sm-6 col-xs-12">
|
||||
<div key={index} className="StepBox col-lg-3 col-sm-6 col-xs-12">
|
||||
<h4 className="StepBox-title">{step.name}</h4>
|
||||
<div className="StepBox-screen">
|
||||
<img className="StepBox-screen-img" src={step.image} />
|
||||
|
@ -66,7 +63,7 @@ const FinalSteps: React.SFC<Props> = ({ walletType }) => {
|
|||
</div>
|
||||
<div className="FinalSteps-buttons">
|
||||
<Link to="/account" className="FinalSteps-buttons-btn btn btn-primary btn-lg">
|
||||
Go to Account
|
||||
{translate('GO_TO_ACCOUNT')}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { IV3Wallet } from 'ethereumjs-wallet';
|
||||
import React, { Component } from 'react';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { makeBlob } from 'utils/blob';
|
||||
import './DownloadWallet.scss';
|
||||
import Template from '../Template';
|
||||
|
@ -27,32 +27,24 @@ export default class DownloadWallet extends Component<Props, State> {
|
|||
return (
|
||||
<Template>
|
||||
<div className="DlWallet">
|
||||
<h1 className="DlWallet-title">{translate('GEN_Label_2')}</h1>
|
||||
<h1 className="DlWallet-title">{translate('GEN_LABEL_2')}</h1>
|
||||
|
||||
<a
|
||||
role="button"
|
||||
className="DlWallet-download btn btn-primary btn-lg"
|
||||
aria-label="Download Keystore File (UTC / JSON · Recommended · Encrypted)"
|
||||
aria-describedby={translate('x_KeystoreDesc', true)}
|
||||
aria-describedby={translateRaw('X_KEYSTOREDESC')}
|
||||
download={filename}
|
||||
href={this.getBlob()}
|
||||
onClick={this.handleDownloadKeystore}
|
||||
>
|
||||
{translate('x_Download')} {translate('x_Keystore2')}
|
||||
{translate('ACTION_13', { $thing: translateRaw('X_KEYSTORE2') })}
|
||||
</a>
|
||||
|
||||
<div className="DlWallet-warning">
|
||||
<p>
|
||||
<strong>Do not lose it!</strong> It cannot be recovered if you lose it.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Do not share it!</strong> Your funds will be stolen if you use this file on a
|
||||
malicious/phishing site.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Make a backup!</strong> Secure it like the millions of dollars it may one day
|
||||
be worth.
|
||||
</p>
|
||||
<p>{translate('DL_WALLET_WARNING_1')}</p>
|
||||
<p>{translate('DL_WALLET_WARNING_2')}</p>
|
||||
<p>{translate('DL_WALLET_WARNING_3')}</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
|
@ -61,7 +53,7 @@ export default class DownloadWallet extends Component<Props, State> {
|
|||
onClick={this.handleContinue}
|
||||
disabled={!hasDownloadedWallet}
|
||||
>
|
||||
I understand. Continue.
|
||||
{translate('ACTION_14')}
|
||||
</button>
|
||||
</div>
|
||||
</Template>
|
||||
|
|
|
@ -33,21 +33,22 @@ export default class EnterPassword extends Component<Props, State> {
|
|||
const isPasswordValid = passwordValidity === 'valid';
|
||||
const isConfirmValid = confirmedPassword ? password === confirmedPassword : undefined;
|
||||
const canSubmit = isPasswordValid && isConfirmValid && !isGenerating;
|
||||
|
||||
return (
|
||||
<Template>
|
||||
<form className="EnterPw" onSubmit={canSubmit ? this.handleSubmit : undefined}>
|
||||
<h1 className="EnterPw-title" aria-live="polite">
|
||||
Generate a {translate('x_Keystore2')}
|
||||
{translate('GENERATE_KEYSTORE_TITLE')}
|
||||
</h1>
|
||||
|
||||
<div className="input-group-wrapper EnterPw-password">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('GEN_Label_1')}</div>
|
||||
<div className="input-group-header">{translate('INPUT_PASSWORD_LABEL')}</div>
|
||||
<TogglablePassword
|
||||
className={!isPasswordValid && password.length > 0 ? 'invalid' : ''}
|
||||
isValid={isPasswordValid && password.length > 0}
|
||||
value={password}
|
||||
placeholder={`Password must be uncommon and ${MINIMUM_PASSWORD_LENGTH}+ characters long`}
|
||||
placeholder={translateRaw('INPUT_PASSWORD_PLACEHOLDER', {
|
||||
$pass_length: MINIMUM_PASSWORD_LENGTH.toString()
|
||||
})}
|
||||
onChange={this.onPasswordChange}
|
||||
onBlur={this.showFeedback}
|
||||
/>
|
||||
|
@ -62,21 +63,21 @@ export default class EnterPassword extends Component<Props, State> {
|
|||
|
||||
<div className="input-group-wrapper EnterPw-password">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">Confirm password</div>
|
||||
<div className="input-group-header">{translate('INPUT_CONFIRM_PASSWORD_LABEL')}</div>
|
||||
<TogglablePassword
|
||||
className={!isConfirmValid && password.length > 0 ? 'invalid' : ''}
|
||||
isValid={isConfirmValid && password.length > 0}
|
||||
value={confirmedPassword}
|
||||
placeholder={translateRaw('GEN_Placeholder_1')}
|
||||
placeholder={translateRaw('GEN_PLACEHOLDER_1')}
|
||||
onChange={this.onConfirmChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button disabled={!canSubmit} className="EnterPw-submit btn btn-primary btn-lg btn-block">
|
||||
{isGenerating ? <Spinner light={true} /> : translate('NAV_GenerateWallet')}
|
||||
{isGenerating ? <Spinner light={true} /> : translate('NAV_GENERATEWALLET')}
|
||||
</button>
|
||||
|
||||
<p className="EnterPw-warning">{translate('x_PasswordDesc')}</p>
|
||||
<p className="EnterPw-warning">{translate('X_PASSWORDDESC')}</p>
|
||||
</form>
|
||||
</Template>
|
||||
);
|
||||
|
@ -101,18 +102,20 @@ export default class EnterPassword extends Component<Props, State> {
|
|||
}
|
||||
|
||||
private getFeedback() {
|
||||
let feedback = '';
|
||||
let feedback: string = '';
|
||||
const validity = this.getPasswordValidity();
|
||||
|
||||
if (validity !== 'valid') {
|
||||
const { password, passwordValidation } = this.state;
|
||||
|
||||
if (password.length < MINIMUM_PASSWORD_LENGTH) {
|
||||
feedback = `Password must be ${MINIMUM_PASSWORD_LENGTH}+ characters`;
|
||||
feedback = translateRaw('INPUT_PASSWORD_PLACEHOLDER', {
|
||||
$pass_length: MINIMUM_PASSWORD_LENGTH.toString()
|
||||
});
|
||||
} else if (passwordValidation && passwordValidation.feedback) {
|
||||
feedback = `This password is not strong enough. ${passwordValidation.feedback.warning}.`;
|
||||
feedback = translateRaw('WEAK_PASSWORD') + ' ' + passwordValidation.feedback.warning;
|
||||
} else {
|
||||
feedback = 'There is something invalid about your password. Please try another.';
|
||||
feedback = translateRaw('INVALID_PASSWORD');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,10 @@ const PaperWallet: React.SFC<Props> = props => (
|
|||
<div className="GenPaper">
|
||||
{/* Private Key */}
|
||||
<label className="input-group GenPaper-private">
|
||||
{/* translateRaw isn't used here because it wont properly render the ` characters as a string of code in markdown*/}
|
||||
<h1 className="input-group-header">{translate('GEN_Label_5')}</h1>
|
||||
<h1 className="GenPaper-title">{translate('GEN_LABEL_5')}</h1>
|
||||
<Input
|
||||
value={stripHexPrefix(props.privateKey)}
|
||||
aria-label={translateRaw('x_PrivKey')}
|
||||
aria-label={translateRaw('X_PRIVKEY')}
|
||||
aria-describedby="x_PrivKeyDesc"
|
||||
type="text"
|
||||
readOnly={true}
|
||||
|
@ -30,29 +29,21 @@ const PaperWallet: React.SFC<Props> = props => (
|
|||
</label>
|
||||
|
||||
{/* Download Paper Wallet */}
|
||||
<h2 className="GenPaper-title">{translate('x_Print')}</h2>
|
||||
<h2 className="GenPaper-title">{translate('X_PRINT')}</h2>
|
||||
<div className="GenPaper-paper">
|
||||
<PrintableWallet address={props.keystore.address} privateKey={props.privateKey} />
|
||||
</div>
|
||||
|
||||
{/* Warning */}
|
||||
<div className="GenPaper-warning">
|
||||
<p>
|
||||
<strong>Do not lose it!</strong> It cannot be recovered if you lose it.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Do not share it!</strong> Your funds will be stolen if you use this file on a
|
||||
malicious/phishing site.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Make a backup!</strong> Secure it like the millions of dollars it may one day be
|
||||
worth.
|
||||
</p>
|
||||
<p>{translate('DL_WALLET_WARNING_1')}</p>
|
||||
<p>{translate('DL_WALLET_WARNING_2')}</p>
|
||||
<p>{translate('DL_WALLET_WARNING_3')}</p>
|
||||
</div>
|
||||
|
||||
{/* Continue button */}
|
||||
<button className="GenPaper-continue btn btn-default" onClick={props.continue}>
|
||||
{translate('NAV_ViewWallet')} →
|
||||
{translate('NAV_VIEWWALLET')} →
|
||||
</button>
|
||||
</div>
|
||||
</Template>
|
||||
|
|
|
@ -51,19 +51,12 @@ export default class GenerateMnemonic extends React.Component<{}, State> {
|
|||
|
||||
content = (
|
||||
<div className="GenerateMnemonic">
|
||||
<h1 className="GenerateMnemonic-title">Generate a {translate('x_Mnemonic')}</h1>
|
||||
<h1 className="GenerateMnemonic-title">{translate('GENERATE_MNEMONIC_TITLE')}</h1>
|
||||
|
||||
<p className="GenerateMnemonic-help">
|
||||
{isConfirming
|
||||
? `
|
||||
Re-enter your phrase to confirm you copied it correctly. If you
|
||||
forgot one of your words, just click the button beside the input
|
||||
to reveal it.
|
||||
`
|
||||
: `
|
||||
Write these words down. Do not copy them to your clipboard, or save
|
||||
them anywhere online.
|
||||
`}
|
||||
? translate('MNEMONIC_DESCRIPTOION_1')
|
||||
: translate('MNEMONIC_DESCRIPTOION_2')}
|
||||
</p>
|
||||
|
||||
<div className="GenerateMnemonic-words">
|
||||
|
@ -80,7 +73,7 @@ export default class GenerateMnemonic extends React.Component<{}, State> {
|
|||
className="GenerateMnemonic-buttons-btn btn btn-default"
|
||||
onClick={this.regenerateWordArray}
|
||||
>
|
||||
<i className="fa fa-refresh" /> Regenerate Phrase
|
||||
<i className="fa fa-refresh" /> {translate('REGENERATE_MNEMONIC')}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
|
@ -88,7 +81,7 @@ export default class GenerateMnemonic extends React.Component<{}, State> {
|
|||
disabled={!canContinue}
|
||||
onClick={this.goToNextStep}
|
||||
>
|
||||
Confirm Phrase
|
||||
{translate('CONFIRM_MNEMONIC')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class MnemonicWord extends React.Component<Props, State> {
|
|||
{!isReadOnly && (
|
||||
<span
|
||||
onClick={this.toggleShow}
|
||||
aria-label={translateRaw('GEN_Aria_2')}
|
||||
aria-label={translateRaw('GEN_ARIA_2')}
|
||||
role="button"
|
||||
className="MnemonicWord-word-toggle input-group-addon"
|
||||
>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import './Template.scss';
|
||||
import translate from 'translations';
|
||||
|
||||
interface Props {
|
||||
children: React.ReactElement<any>;
|
||||
|
@ -10,7 +11,7 @@ const GenerateWalletTemplate: React.SFC<Props> = ({ children }) => (
|
|||
<div className="GenerateWallet Tab-content-pane">
|
||||
{children}
|
||||
<Link className="GenerateWallet-back" to="/generate">
|
||||
<i className="fa fa-arrow-left" /> Back
|
||||
<i className="fa fa-arrow-left" /> {translate('MODAL_BACK')}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { WalletType } from '../GenerateWallet';
|
||||
import { NewTabLink, HelpLink } from 'components/ui';
|
||||
import { HELP_ARTICLE, trezorReferralURL, ledgerReferralURL } from 'config';
|
||||
import { Link } from 'react-router-dom';
|
||||
import './WalletTypes.scss';
|
||||
import { HelpLink } from 'components/ui';
|
||||
import { HELP_ARTICLE, ledgerReferralURL, trezorReferralURL } from 'config';
|
||||
|
||||
const WalletTypes: React.SFC<{}> = () => {
|
||||
const typeInfo = {
|
||||
[WalletType.Keystore]: {
|
||||
name: 'x_Keystore2',
|
||||
name: 'X_KEYSTORE2',
|
||||
bullets: [
|
||||
'An encrypted JSON file, protected by a password',
|
||||
'Back it up on a USB drive',
|
||||
|
@ -19,7 +19,7 @@ const WalletTypes: React.SFC<{}> = () => {
|
|||
]
|
||||
},
|
||||
[WalletType.Mnemonic]: {
|
||||
name: 'x_Mnemonic',
|
||||
name: 'X_MNEMONIC',
|
||||
bullets: [
|
||||
'A 12-word private seed phrase',
|
||||
'Back it up on paper or USB drive',
|
||||
|
@ -32,15 +32,16 @@ const WalletTypes: React.SFC<{}> = () => {
|
|||
|
||||
return (
|
||||
<div className="WalletTypes Tab-content-pane">
|
||||
<h1 className="WalletTypes-title">{translate('NAV_GenerateWallet')}</h1>
|
||||
<h1 className="WalletTypes-title">{translate('NAV_GENERATEWALLET')}</h1>
|
||||
<p className="WalletTypes-subtitle alert alert-warning">
|
||||
<strong>Warning</strong>: Managing your own keys can be risky and a single mistake can lead
|
||||
to irrecoverable loss. If you are new to cryptocurrencies, we strongly recommend using{' '}
|
||||
<NewTabLink href="https://metamask.io/">MetaMask</NewTabLink>, or purchasing a{' '}
|
||||
<NewTabLink href={ledgerReferralURL}>Ledger</NewTabLink> or{' '}
|
||||
<NewTabLink href={trezorReferralURL}>TREZOR</NewTabLink> hardware wallet.{' '}
|
||||
<strong>{translate('NOTIFICATION_TYPE_WARNING')}</strong>:{' '}
|
||||
{translate('GENERATE_WALLET_WARNING', {
|
||||
$metamask_link: 'https://metamask.io/',
|
||||
$ledger_link: ledgerReferralURL,
|
||||
$trezor_link: trezorReferralURL
|
||||
})}
|
||||
<HelpLink article={HELP_ARTICLE.DIFFERENCE_BETWEEN_PKEY_AND_KEYSTORE}>
|
||||
Learn more about different wallet types & staying secure.
|
||||
{translate('GENERATE_WALLET_HELPLINK_1')}
|
||||
</HelpLink>
|
||||
</p>
|
||||
|
||||
|
@ -61,7 +62,7 @@ const WalletTypes: React.SFC<{}> = () => {
|
|||
className="WalletType-select-btn btn btn-primary btn-block"
|
||||
to={`/generate/${type}`}
|
||||
>
|
||||
Generate a {translate(typeInfo[type].name)}
|
||||
{translate('GENERATE_THING', { $thing: translateRaw(typeInfo[type].name) })}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { donationAddressMap } from 'config';
|
||||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
|
||||
interface Props {
|
||||
onDonate(address: string, amount: string, unit: string): void;
|
||||
}
|
||||
interface State {
|
||||
clicked: boolean;
|
||||
}
|
||||
export default class Donate extends React.Component<Props, State> {
|
||||
public state = {
|
||||
clicked: false
|
||||
};
|
||||
public render() {
|
||||
return (
|
||||
<div className="well">
|
||||
<p>{translate('SIDEBAR_DONATION')}</p>
|
||||
<a className="btn btn-primary btn-block" onClick={this.onClick}>
|
||||
{translate('SIDEBAR_DONATE')}
|
||||
</a>
|
||||
{this.state.clicked && (
|
||||
<div className="text-success text-center marg-v-sm">{translate('SIDEBAR_THANKS')}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public onClick = () => {
|
||||
// FIXME move to config
|
||||
this.props.onDonate(donationAddressMap.ETH, '1', 'ETH');
|
||||
|
||||
this.setState({ clicked: true });
|
||||
};
|
||||
}
|
|
@ -52,7 +52,7 @@ const QueryWarning: React.SFC<{}> = () => (
|
|||
<WhenQueryExists
|
||||
whenQueryExists={
|
||||
<div className="alert alert-info">
|
||||
<p>{translate('WARN_Send_Link')}</p>
|
||||
<p>{translate('WARN_SEND_LINK')}</p>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { getRecentWalletTransactions } from 'selectors/transactions';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import RecentTransaction from './RecentTransaction';
|
||||
import { TransactionStatus } from 'components';
|
||||
import { IWallet } from 'libs/wallet';
|
||||
|
@ -39,7 +38,7 @@ class RecentTransactions extends React.Component<Props> {
|
|||
<React.Fragment>
|
||||
<TransactionStatus txHash={activeTxHash} />
|
||||
<button className="RecentTxs-back btn btn-default" onClick={this.clearActiveTxHash}>
|
||||
<i className="fa fa-arrow-left" /> Back to Recent Transactions
|
||||
<i className="fa fa-arrow-left" /> {translate('BACK_TO_RECENT_TXS')}
|
||||
</button>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
@ -53,15 +52,13 @@ class RecentTransactions extends React.Component<Props> {
|
|||
private renderTxList() {
|
||||
const { wallet, recentTransactions, network } = this.props;
|
||||
|
||||
let explorer: React.ReactElement<string>;
|
||||
let explorer: string;
|
||||
if (network.isCustom) {
|
||||
explorer = <span>an explorer for the {network.name} network</span>;
|
||||
explorer = translateRaw('RECENT_TX_NETWORK_EXPLORER', { $network_name: network.name });
|
||||
} else {
|
||||
explorer = (
|
||||
<NewTabLink href={network.blockExplorer.addressUrl(wallet.getAddressString())}>
|
||||
{network.blockExplorer.name}
|
||||
</NewTabLink>
|
||||
);
|
||||
explorer = `[${network.blockExplorer.name}](${network.blockExplorer.addressUrl(
|
||||
wallet.getAddressString()
|
||||
)})`;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -69,9 +66,9 @@ class RecentTransactions extends React.Component<Props> {
|
|||
{recentTransactions.length ? (
|
||||
<table className="RecentTxs-txs">
|
||||
<thead>
|
||||
<td>{translate('SEND_addr')}</td>
|
||||
<td>{translate('SEND_amount_short')}</td>
|
||||
<td>{translate('Sent')}</td>
|
||||
<td>{translate('SEND_ADDR')}</td>
|
||||
<td>{translate('SEND_AMOUNT_SHORT')}</td>
|
||||
<td>{translate('SENT')}</td>
|
||||
<td />
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -88,13 +85,12 @@ class RecentTransactions extends React.Component<Props> {
|
|||
) : (
|
||||
<div className="RecentTxs-empty well">
|
||||
<h2 className="RecentTxs-empty-text">
|
||||
No recent MyCrypto transactions found, try checking on {explorer}.
|
||||
{translate('NO_RECENT_TX_FOUND', { $explorer: explorer })}
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
<p className="RecentTxs-help">
|
||||
Only recent transactions sent from this address via MyCrypto on the {network.name} network
|
||||
are listed here. If you don't see your transaction, you can view all of them on {explorer}.
|
||||
{translate('RECENT_TX_HELP', { $network: network.name, $explorer: explorer })}
|
||||
</p>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
@ -123,7 +123,9 @@ class RequestPayment extends React.Component<Props, {}> {
|
|||
|
||||
{!!eip681String.length && (
|
||||
<div className="row form-group">
|
||||
<label className="RequestPayment-title">{translate('Payment QR & Code')}</label>
|
||||
<label className="RequestPayment-title">
|
||||
{translate('REQUEST_PAYMENT_QR_TITLE')}
|
||||
</label>
|
||||
<div className="col-xs-6">
|
||||
<div className="RequestPayment-qr well well-lg">
|
||||
<QRCode data={eip681String} />
|
||||
|
|
|
@ -46,7 +46,7 @@ export default class WalletInfo extends React.PureComponent<Props, State> {
|
|||
<div className="col-xs-11">
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('x_Address')}</div>
|
||||
<div className="input-group-header">{translate('X_ADDRESS')}</div>
|
||||
<Input readOnly={true} value={address} />
|
||||
</label>
|
||||
</div>
|
||||
|
@ -59,12 +59,12 @@ export default class WalletInfo extends React.PureComponent<Props, State> {
|
|||
{privateKey && (
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<label>{translate('x_PrivKey')}</label>
|
||||
<label>{translate('X_PRIVKEY')}</label>
|
||||
<TogglablePassword
|
||||
disabled={true}
|
||||
value={privateKey}
|
||||
isVisible={isPrivateKeyVisible}
|
||||
toggleAriaLabel={translateRaw('GEN_Aria_2')}
|
||||
toggleAriaLabel={translateRaw('GEN_ARIA_2')}
|
||||
handleToggleVisibility={this.togglePrivateKey}
|
||||
/>
|
||||
</div>
|
||||
|
@ -75,7 +75,7 @@ export default class WalletInfo extends React.PureComponent<Props, State> {
|
|||
<div className="Tab-content-pane">
|
||||
<div className="row">
|
||||
<div className="col-xs-6">
|
||||
<label>Public Address</label>
|
||||
<label>{translate('TOKEN_ADDR')}</label>
|
||||
<div className="WalletInfo-qr well well-lg">
|
||||
<QRCode data={address} />
|
||||
</div>
|
||||
|
@ -83,7 +83,7 @@ export default class WalletInfo extends React.PureComponent<Props, State> {
|
|||
{privateKey && (
|
||||
<div>
|
||||
<div className="col-xs-6">
|
||||
<label>Private Key</label>
|
||||
<label>{translate('X_PRIVKEY2')}</label>
|
||||
<div className="WalletInfo-qr well well-lg" onClick={this.togglePrivateKey}>
|
||||
<QRCode data={isPrivateKeyVisible ? privateKey : '0'} />
|
||||
{!isPrivateKeyVisible && (
|
||||
|
@ -95,14 +95,14 @@ export default class WalletInfo extends React.PureComponent<Props, State> {
|
|||
</div>
|
||||
|
||||
<div className="col-xs-6">
|
||||
<label>Utilities</label>
|
||||
<label>{translate('WALLET_INFO_UTILITIES')}</label>
|
||||
|
||||
<button className="btn btn-info btn-block" onClick={print(address, privateKey)}>
|
||||
{translate('x_Print')}
|
||||
{translate('X_PRINT')}
|
||||
</button>
|
||||
|
||||
<button className="btn btn-info btn-block" onClick={this.toggleKeystoreModal}>
|
||||
Generate Keystore File
|
||||
{translate('GENERATE_KEYSTORE_TITLE')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import TabSection from 'containers/TabSection';
|
||||
import { UnlockHeader } from 'components/ui';
|
||||
import { getWalletInst } from 'selectors/wallet';
|
||||
|
@ -40,28 +40,28 @@ class SendTransaction extends React.Component<Props> {
|
|||
const tabs: Tab[] = [
|
||||
{
|
||||
path: 'send',
|
||||
name: translate('NAV_SendEther'),
|
||||
name: translate('NAV_SENDETHER'),
|
||||
disabled: !!wallet && !!wallet.isReadOnly
|
||||
},
|
||||
{
|
||||
path: 'request',
|
||||
name: translate('Request Payment'),
|
||||
name: translate('NAV_REQUESTPAYMENT'),
|
||||
disabled: this.props.requestDisabled
|
||||
},
|
||||
{
|
||||
path: 'info',
|
||||
name: translate('NAV_ViewWallet')
|
||||
name: translate('NAV_VIEWWALLET')
|
||||
},
|
||||
{
|
||||
path: 'recent-txs',
|
||||
name: translate('Recent Transactions')
|
||||
name: translate('NAV_RECENT_TX')
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<TabSection>
|
||||
<section className="Tab-content">
|
||||
<UnlockHeader title={translate('Account')} showGenerateLink={true} />
|
||||
<UnlockHeader title={translateRaw('ACCOUNT')} showGenerateLink={true} />
|
||||
{wallet && (
|
||||
<div className="SubTabs row">
|
||||
<div className="col-sm-8">
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class SignMessageButton extends React.Component<Props, {}> {
|
|||
public render() {
|
||||
return (
|
||||
<button className="SignMessage-sign btn btn-primary btn-lg" onClick={this.handleSignMessage}>
|
||||
{translate('NAV_SignMsg')}
|
||||
{translate('NAV_SIGNMSG')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ export default class SignMessageButton extends React.Component<Props, {}> {
|
|||
onSignMessage(signedMessage);
|
||||
showNotification(
|
||||
'success',
|
||||
`Successfully signed message with address ${signedMessage.address}.`
|
||||
translate('SIGN_MSG_SUCCESS', { $address: signedMessage.address })
|
||||
);
|
||||
} catch (err) {
|
||||
showNotification('danger', `Error signing message: ${err.message}`);
|
||||
showNotification('danger', translate('SIGN_MSG_FAIL', { $err: err.message }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import WalletDecrypt, { DISABLE_WALLETS } from 'components/WalletDecrypt';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||
import { resetWallet, TResetWallet } from 'actions/wallet';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
|
@ -29,8 +29,7 @@ const initialState: State = {
|
|||
signedMessage: null
|
||||
};
|
||||
|
||||
const messagePlaceholder =
|
||||
'This is a sweet message that you are signing to prove that you own the address you say you own.';
|
||||
const messagePlaceholder = translateRaw('SIGN_MSG_PLACEHOLDER');
|
||||
|
||||
export class SignMessage extends Component<Props, State> {
|
||||
public state: State = initialState;
|
||||
|
@ -52,12 +51,12 @@ export class SignMessage extends Component<Props, State> {
|
|||
onClick={this.changeWallet}
|
||||
>
|
||||
<i className="fa fa-refresh" />
|
||||
{translate('Change Wallet')}
|
||||
{translate('CHANGE_WALLET')}
|
||||
</button>
|
||||
|
||||
<div className="input-group-wrapper Deploy-field">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('MSG_message')}</div>
|
||||
<div className="input-group-header">{translate('MSG_MESSAGE')}</div>
|
||||
<TextArea
|
||||
className={`SignMessage-inputBox ${message ? 'is-valid' : 'is-invalid'}`}
|
||||
placeholder={messagePlaceholder}
|
||||
|
@ -65,7 +64,7 @@ export class SignMessage extends Component<Props, State> {
|
|||
onChange={this.handleMessageChange}
|
||||
/>
|
||||
</label>
|
||||
<div className="SignMessage-help">{translate('MSG_info2')}</div>
|
||||
<div className="SignMessage-help">{translate('MSG_INFO2')}</div>
|
||||
</div>
|
||||
|
||||
<SignButton
|
||||
|
@ -78,7 +77,7 @@ export class SignMessage extends Component<Props, State> {
|
|||
{!!signedMessage && (
|
||||
<div className="input-group-wrapper SignMessage-inputBox">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('MSG_signature')}</div>
|
||||
<div className="input-group-header">{translate('MSG_SIGNATURE')}</div>
|
||||
<TextArea
|
||||
className="SignMessage-inputBox"
|
||||
value={JSON.stringify(signedMessage, null, 2)}
|
||||
|
|
|
@ -39,7 +39,7 @@ export class VerifyMessage extends Component<Props, State> {
|
|||
<div className="Tab-content-pane">
|
||||
<div className="input-group-wrapper ">
|
||||
<label className="input-group">
|
||||
<div className="input-group-header">{translate('MSG_signature')}</div>
|
||||
<div className="input-group-header">{translate('MSG_SIGNATURE')}</div>
|
||||
<TextArea
|
||||
className={`VerifyMessage-inputBox ${signature ? 'is-valid' : 'is-invalid'}`}
|
||||
placeholder={signaturePlaceholder}
|
||||
|
@ -55,13 +55,13 @@ export class VerifyMessage extends Component<Props, State> {
|
|||
onClick={this.handleVerifySignedMessage}
|
||||
disabled={false}
|
||||
>
|
||||
{translate('MSG_verify')}
|
||||
{translate('MSG_VERIFY')}
|
||||
</button>
|
||||
|
||||
{!!verifiedAddress &&
|
||||
!!verifiedMessage && (
|
||||
<div className="VerifyMessage-success alert alert-success">
|
||||
<strong>{verifiedAddress}</strong> did sign the message{' '}
|
||||
<strong>{verifiedAddress}</strong> {translate('SIGNED')}
|
||||
<strong>{verifiedMessage}</strong>.
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -25,11 +25,11 @@ export default class SignAndVerifyMessage extends Component<RouteComponentProps<
|
|||
const tabs = [
|
||||
{
|
||||
path: 'sign',
|
||||
name: translate('NAV_SignMsg')
|
||||
name: translate('NAV_SIGNMSG')
|
||||
},
|
||||
{
|
||||
path: 'verify',
|
||||
name: translate('MSG_verify')
|
||||
name: translate('MSG_VERIFY')
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
import translate from 'translations';
|
||||
import QRCode from 'qrcode.react';
|
||||
import './BitcoinQR.scss';
|
||||
|
||||
|
@ -13,19 +14,15 @@ export default class BitcoinQR extends PureComponent<Props, {}> {
|
|||
return (
|
||||
<div className="BitcoinQR">
|
||||
<section className="row block swap-address text-center">
|
||||
<label> Your Address </label>
|
||||
<label>{translate('X_ADDRESS')}</label>
|
||||
<div className="BitcoinQR-qr">
|
||||
<QRCode value={`bitcoin:${paymentAddress}amount=${destinationAmount}`} />
|
||||
</div>
|
||||
<br />
|
||||
<p className="text-danger">
|
||||
Orders that take too long will have to be processed manually & and may delay the
|
||||
amount of time it takes to receive your coins.
|
||||
<br />
|
||||
<a href="https://shapeshift.io/#/btcfee" target="_blank" rel="noopener noreferrer">
|
||||
Please use the recommended TX fees seen here.
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-danger">{translate('SWAP_TIME_LIMIT_WARNING')}</p>
|
||||
{translate('SWAP_RECOMMENDED_TX_FEES', {
|
||||
$link: 'https://shapeshift.io/#/btcfee'
|
||||
})}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
import SimpleButton from 'components/ui/SimpleButton';
|
||||
import { generateKindMax, generateKindMin, WhitelistedCoins, bityConfig } from 'config/bity';
|
||||
import React, { PureComponent } from 'react';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { combineAndUpper } from 'utils/formatters';
|
||||
import { SwapDropdown, Input } from 'components/ui';
|
||||
import Spinner from 'components/ui/Spinner';
|
||||
|
@ -81,9 +81,15 @@ export default class CurrencySwap extends PureComponent<Props, State> {
|
|||
const rate = this.getMinMax(originKind, destKind);
|
||||
let errString;
|
||||
if (amount > rate.max) {
|
||||
errString = `Maximum ${rate.max} ${originKind}`;
|
||||
errString = translateRaw('SWAP_MAX_ERROR', {
|
||||
$rate_max: rate.max.toString(),
|
||||
$origin_id: originKind
|
||||
});
|
||||
} else {
|
||||
errString = `Minimum ${rate.min} ${originKind}`;
|
||||
errString = translateRaw('SWAP_MIN_ERROR', {
|
||||
$rate_max: rate.min.toString(),
|
||||
$origin_id: originKind
|
||||
});
|
||||
}
|
||||
return errString;
|
||||
};
|
||||
|
@ -340,7 +346,7 @@ export default class CurrencySwap extends PureComponent<Props, State> {
|
|||
<div className="CurrencySwap-inner-wrap">
|
||||
<div className="flex-spacer" />
|
||||
<div className="input-group-wrapper">
|
||||
<div className="input-group-header">Deposit</div>
|
||||
<div className="input-group-header">{translate('SWAP_DEPOSIT_INPUT_LABEL')}</div>
|
||||
<label className="input-group input-group-inline">
|
||||
<Input
|
||||
id="origin-swap-input"
|
||||
|
@ -351,7 +357,7 @@ export default class CurrencySwap extends PureComponent<Props, State> {
|
|||
: 'invalid'
|
||||
}`}
|
||||
type="number"
|
||||
placeholder="Amount"
|
||||
placeholder={translateRaw('SEND_AMOUNT_SHORT')}
|
||||
value={isNaN(origin.amount) ? '' : origin.amount}
|
||||
onChange={this.onChangeAmount}
|
||||
/>
|
||||
|
@ -366,7 +372,7 @@ export default class CurrencySwap extends PureComponent<Props, State> {
|
|||
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group input-group-inline">
|
||||
<div className="input-group-header">Recieve</div>
|
||||
<div className="input-group-header">{translate('SWAP_RECIEVE_INPUT_LABEL')}</div>
|
||||
<Input
|
||||
id="destination-swap-input"
|
||||
className={`${
|
||||
|
@ -376,7 +382,7 @@ export default class CurrencySwap extends PureComponent<Props, State> {
|
|||
: 'invalid'
|
||||
}`}
|
||||
type="number"
|
||||
placeholder="Amount"
|
||||
placeholder={translateRaw('SEND_AMOUNT_SHORT')}
|
||||
value={isNaN(destination.amount) ? '' : destination.amount}
|
||||
onChange={this.onChangeAmount}
|
||||
/>
|
||||
|
@ -395,7 +401,7 @@ export default class CurrencySwap extends PureComponent<Props, State> {
|
|||
<div className="CurrencySwap-submit">
|
||||
<SimpleButton
|
||||
onClick={this.onClickStartSwap}
|
||||
text={translate('SWAP_init_CTA')}
|
||||
text={translateRaw('SWAP_INIT_CTA')}
|
||||
disabled={this.state.disabled}
|
||||
type="primary"
|
||||
/>
|
||||
|
|
|
@ -122,7 +122,7 @@ class CurrentRates extends PureComponent<Props> {
|
|||
public swapEl = (providerURL: string, providerLogo: string, children: any) => {
|
||||
return (
|
||||
<article className="SwapRates">
|
||||
<h3 className="SwapRates-title">{translate('SWAP_rates')}</h3>
|
||||
<h3 className="SwapRates-title">{translate('SWAP_RATES')}</h3>
|
||||
|
||||
<section className="SwapRates-panel row">
|
||||
{children}
|
||||
|
|
|
@ -31,7 +31,7 @@ class FieldsClass extends Component<Props> {
|
|||
onClick={this.changeWallet}
|
||||
>
|
||||
<i className="fa fa-refresh" />
|
||||
{translate('Change Wallet')}
|
||||
{translate('CHANGE_WALLET')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="col-xs-12">
|
||||
|
@ -46,7 +46,7 @@ class FieldsClass extends Component<Props> {
|
|||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<label>{translate('SEND_amount')}</label>
|
||||
<label>{translate('SEND_AMOUNT')}</label>
|
||||
{currentBalance === null ? (
|
||||
<div className="row text-center">
|
||||
<Spinner />
|
||||
|
@ -56,10 +56,7 @@ class FieldsClass extends Component<Props> {
|
|||
withProps={({ currentValue, isValid }) => (
|
||||
<React.Fragment>
|
||||
{!isValid && (
|
||||
<h5 style={{ color: 'red' }}>
|
||||
WARNING: Your ether or token balance is not high enough to complete this
|
||||
transaction! Please send more funds or switch to a different wallet
|
||||
</h5>
|
||||
<h5 style={{ color: 'red' }}>{translate('INSUFFICIENT_FUNDS')}</h5>
|
||||
)}
|
||||
{isValid && (
|
||||
<Input
|
||||
|
|
|
@ -14,19 +14,17 @@ export default class PaymentInfo extends PureComponent<Props, {}> {
|
|||
const { origin } = this.props;
|
||||
return (
|
||||
<section className="SwapPayment">
|
||||
<h1>
|
||||
<span>{translate('SWAP_order_CTA')}</span>
|
||||
<strong>
|
||||
{' '}
|
||||
{origin.amount} {origin.label}
|
||||
</strong>
|
||||
<span> {translate('SENDModal_Content_2')}</span>
|
||||
<h2>
|
||||
{translate('SWAP_SEND_TO', {
|
||||
$origin_amount: origin.amount.toString(),
|
||||
$origin_label: origin.label
|
||||
})}
|
||||
<Input
|
||||
className="SwapPayment-address"
|
||||
value={this.props.paymentAddress || undefined}
|
||||
disabled={true}
|
||||
/>
|
||||
</h1>
|
||||
</h2>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import SimpleButton from 'components/ui/SimpleButton';
|
|||
import { donationAddressMap } from 'config';
|
||||
import { isValidBTCAddress, isValidETHAddress } from 'libs/validators';
|
||||
import React, { PureComponent } from 'react';
|
||||
import translate from 'translations';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { combineAndUpper } from 'utils/formatters';
|
||||
import './ReceivingAddress.scss';
|
||||
import { Input } from 'components/ui';
|
||||
|
@ -75,7 +75,7 @@ export default class ReceivingAddress extends PureComponent<StateProps & ActionP
|
|||
<div className="col-sm-8 col-sm-offset-2 col-xs-12">
|
||||
<label className="SwapAddress-address">
|
||||
<h4 className="SwapAddress-address-label">
|
||||
{translate('SWAP_rec_add')} ({destinationId})
|
||||
{translate('SWAP_REC_ADD')} ({destinationId})
|
||||
</h4>
|
||||
|
||||
<Input
|
||||
|
@ -95,7 +95,7 @@ export default class ReceivingAddress extends PureComponent<StateProps & ActionP
|
|||
|
||||
<section className="SwapAddress-submit row">
|
||||
<SimpleButton
|
||||
text={translate('SWAP_start_CTA')}
|
||||
text={translateRaw('SWAP_START_CTA')}
|
||||
onClick={this.onClickPartTwoComplete}
|
||||
disabled={!validAddress}
|
||||
loading={isPostingOrder}
|
||||
|
|
|
@ -3,6 +3,7 @@ import './SupportFooter.scss';
|
|||
import { SwapInput } from 'actions/swap';
|
||||
import { NormalizedBityRates, NormalizedShapeshiftRates } from 'reducers/swap/types';
|
||||
import { TextArea } from 'components/ui';
|
||||
import translate from 'translations';
|
||||
|
||||
interface Props {
|
||||
origin: SwapInput;
|
||||
|
@ -75,11 +76,11 @@ Rate: ${rates[pair].rate} ${origin.label}/${destination.label}`;
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Issue with your Swap? Contact support
|
||||
{translate('SWAP_SUPPORT')}
|
||||
</a>
|
||||
<div className="SupportFooter-fallback">
|
||||
<p onClick={this.toggleFallback}>
|
||||
<small>Click here if link doesn't work</small>
|
||||
<small>{translate('SWAP_SUPPORT_LINK_BROKEN')}</small>
|
||||
</p>
|
||||
{open ? (
|
||||
<TextArea defaultValue={fallbackBody} className="form-control input-sm" rows={9} />
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue