mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-01-12 03:54:13 +00:00
ab5fa1a799
* Make UnlockHeader a PureComponent * MVP * actually disable wallet format if not determined to be valid format for wallet * default to correct derivation in mnemonic modal * cleanup * fix tslint * use enums for HD wallet getPath * Add stricter typing * Fix labels not updating on selector * Ban hardware wallet support for custom network unsupported chainIds * Fix type error * Fix custom node dPath not being saved * Fix mnemonic modal * default path bugfixes * add react-select * misc fixes; rabbit holing hard. * fix tslint * revert identicon changes * reload on network change :/ * actually reload on network change * really really reload on network change * tslint fixes * Update styles * set table width * fix package versioning * push broken sagas * Fix saga test * fix tslint * address round of review * move non-selectors out to utilty; adjust reload timer * cleanup network util comments * manage wallet disable at WalletDecrypt instead of in both WalletDecrypt and WalletButton * Separate WalletDecrypt props into ownProps / StateProps * disable payment requests on non-eth networks * specialize connect; separate props * remove unused state prop * remove bad import * create tests for networks * Clarify Lite-Send error on non-ethereum networkS * remove string option for network config name * Create concept of always-on 'EXTRA_PATHS'; include SINGULAR_DTV legacy dPath in 'EXTRA_PATHS' * fix multiple imports * address PR comments
178 lines
5.0 KiB
TypeScript
178 lines
5.0 KiB
TypeScript
import React from 'react';
|
|
import { generateKeystoreFileInfo, KeystoreFile } from 'utils/keystore';
|
|
import Modal from 'components/ui/Modal';
|
|
import Input from './Input';
|
|
import translate, { translateRaw } from 'translations';
|
|
import { MINIMUM_PASSWORD_LENGTH } from 'config';
|
|
import { isValidPrivKey } from 'libs/validators';
|
|
import './index.scss';
|
|
|
|
interface Props {
|
|
isOpen: boolean;
|
|
privateKey?: string;
|
|
handleClose(): void;
|
|
}
|
|
|
|
interface State {
|
|
privateKey: string;
|
|
password: string;
|
|
isPrivateKeyVisible: boolean;
|
|
isPasswordVisible: boolean;
|
|
keystoreFile: KeystoreFile | null;
|
|
hasError: boolean;
|
|
}
|
|
|
|
const initialState: State = {
|
|
privateKey: '',
|
|
password: '',
|
|
isPrivateKeyVisible: false,
|
|
isPasswordVisible: false,
|
|
keystoreFile: null,
|
|
hasError: false
|
|
};
|
|
|
|
export default class GenerateKeystoreModal extends React.Component<Props, State> {
|
|
public state: State = initialState;
|
|
|
|
constructor(props: Props) {
|
|
super(props);
|
|
|
|
if (props.privateKey) {
|
|
this.state = {
|
|
...this.state,
|
|
privateKey: props.privateKey
|
|
};
|
|
}
|
|
}
|
|
|
|
public componentWillReceiveProps(nextProps) {
|
|
if (nextProps.privateKey !== this.props.privateKey) {
|
|
this.setState({ privateKey: nextProps.privateKey });
|
|
}
|
|
}
|
|
|
|
public render() {
|
|
const {
|
|
privateKey,
|
|
password,
|
|
isPrivateKeyVisible,
|
|
isPasswordVisible,
|
|
keystoreFile,
|
|
hasError
|
|
} = this.state;
|
|
|
|
const isPrivateKeyValid = isValidPrivKey(privateKey);
|
|
const isPasswordValid = password.length >= MINIMUM_PASSWORD_LENGTH;
|
|
|
|
return (
|
|
<Modal
|
|
title={translate('Generate Keystore File')}
|
|
isOpen={this.props.isOpen}
|
|
handleClose={this.handleClose}
|
|
>
|
|
<form className="GenKeystore" onSubmit={this.handleSubmit}>
|
|
<label className="GenKeystore-field">
|
|
<h4 className="GenKeystore-field-label">Private Key</h4>
|
|
<Input
|
|
isValid={isPrivateKeyValid}
|
|
isVisible={isPrivateKeyVisible}
|
|
name="privateKey"
|
|
value={privateKey}
|
|
handleInput={this.handleInput}
|
|
placeholder="f1d0e0789c6d40f39..."
|
|
handleToggle={this.togglePrivateKey}
|
|
disabled={!!this.props.privateKey}
|
|
/>
|
|
</label>
|
|
<label className="GenKeystore-field">
|
|
<h4 className="GenKeystore-field-label">Password</h4>
|
|
<Input
|
|
isValid={isPasswordValid}
|
|
isVisible={isPasswordVisible}
|
|
name="password"
|
|
value={password}
|
|
placeholder={translateRaw('Minimum 9 characters')}
|
|
handleInput={this.handleInput}
|
|
handleToggle={this.togglePassword}
|
|
/>
|
|
</label>
|
|
|
|
{!keystoreFile ? (
|
|
<button
|
|
className="GenKeystore-button btn btn-primary btn-block"
|
|
disabled={!isPrivateKeyValid || !isPasswordValid}
|
|
>
|
|
{translate('Generate Keystore File')}
|
|
</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>
|
|
) : (
|
|
<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')}
|
|
download={keystoreFile.filename}
|
|
>
|
|
{translate('Download Keystore File')}
|
|
</a>
|
|
)}
|
|
</form>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
private togglePrivateKey = () => {
|
|
this.setState({
|
|
isPrivateKeyVisible: !this.state.isPrivateKeyVisible
|
|
});
|
|
};
|
|
|
|
private togglePassword = () => {
|
|
this.setState({
|
|
isPasswordVisible: !this.state.isPasswordVisible
|
|
});
|
|
};
|
|
|
|
private handleInput = (e: React.FormEvent<HTMLInputElement>) => {
|
|
const { name, value } = e.currentTarget;
|
|
let { keystoreFile } = this.state;
|
|
if (name === 'privateKey') {
|
|
keystoreFile = null;
|
|
}
|
|
this.setState({ [name as any]: value, keystoreFile });
|
|
};
|
|
|
|
private handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
if (!this.state.keystoreFile) {
|
|
this.generateKeystoreFileInfo();
|
|
}
|
|
};
|
|
|
|
private generateKeystoreFileInfo = async () => {
|
|
try {
|
|
const { privateKey, password } = this.state;
|
|
const keystoreFile = await generateKeystoreFileInfo(privateKey, password);
|
|
if (keystoreFile) {
|
|
this.setState({ keystoreFile });
|
|
}
|
|
} catch (err) {
|
|
this.setState({ hasError: true });
|
|
}
|
|
};
|
|
|
|
private handleClose = () => {
|
|
this.setState({
|
|
...initialState,
|
|
privateKey: this.props.privateKey || initialState.privateKey
|
|
});
|
|
this.props.handleClose();
|
|
};
|
|
}
|