|
|
|
@ -22,9 +22,20 @@ import { SelectComponent } from '../components/select';
|
|
|
|
|
import rpc from '../../services/api';
|
|
|
|
|
import { DARK, LIGHT, THEME_MODE } from '../constants/themes';
|
|
|
|
|
import electronStore from '../../config/electron-store';
|
|
|
|
|
import { openExternal } from '../utils/open-external';
|
|
|
|
|
|
|
|
|
|
const HOME_DIR = electron.remote.app.getPath('home');
|
|
|
|
|
|
|
|
|
|
const EXPORT_VIEW_KEYS_TITLE = 'Export View Keys';
|
|
|
|
|
const EXPORT_VIEW_KEYS_CONTENT = 'Viewing keys for shielded addresses allow for the disclosure of all transaction information to a preffered party. Anyone who holds these keys can see all shielded transaction details, but cannot spend coins as it is not a private key.';
|
|
|
|
|
const EXPORT_VIEW_KEYS_LEARN_MORE = 'https://z.cash/blog/viewing-keys-selective-disclosure';
|
|
|
|
|
const IMPORT_PRIV_KEYS_TITLE = 'Import Private Keys';
|
|
|
|
|
const IMPORT_PRIV_KEYS_CONTENT = 'Importing private keys will add the spendable coins to this wallet.';
|
|
|
|
|
const EXPORT_PRIV_KEYS_TITLE = 'Export Private Keys';
|
|
|
|
|
const EXPORT_PRIV_KEYS_CONTENT = 'Beware: exporting your private keys will allow anyone controlling them to spend your coins. Only perform this action on a trusted machine.';
|
|
|
|
|
const BACKUP_WALLET_TITLE = 'Backup Wallet';
|
|
|
|
|
const BACKUP_WALLET_CONTENT = 'It is recommended that you backup your wallet often.';
|
|
|
|
|
|
|
|
|
|
const Wrapper = styled.div`
|
|
|
|
|
margin-top: ${props => props.theme.layoutContentPaddingTop};
|
|
|
|
|
`;
|
|
|
|
@ -52,9 +63,37 @@ const ClipboardButton = styled(Clipboard)`
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const SettingsWrapper = styled.div`
|
|
|
|
|
margin-bottom: 45px;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
min-width: 200px;
|
|
|
|
|
width: 37%;
|
|
|
|
|
width: 70%;
|
|
|
|
|
max-width: 600px;
|
|
|
|
|
min-width: 350px;
|
|
|
|
|
background: ${props => props.theme.colors.settingsCardBg};
|
|
|
|
|
padding: 20px 20px 10px 20px;
|
|
|
|
|
border: 1px solid ${props => props.theme.colors.inputBorder};
|
|
|
|
|
border-radius: ${props => props.theme.boxBorderRadius};
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const SettingsInnerWrapper = styled.div`
|
|
|
|
|
margin-bottom: 50px;
|
|
|
|
|
|
|
|
|
|
&:last-child {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const LearnMore = styled.div`
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
text-transform: uppercase;
|
|
|
|
|
font-size: 10px;
|
|
|
|
|
font-family: Roboto;
|
|
|
|
|
letter-spacing: 1px;
|
|
|
|
|
color: ${props => props.theme.colors.settingsLearnMore};
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
color: ${props => props.theme.colors.settingsLearnMoreHovered};;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const SettingsTitle = styled(TextComponent)`
|
|
|
|
@ -66,12 +105,25 @@ const SettingsTitle = styled(TextComponent)`
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const SettingsContent = styled(TextComponent)`
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
margin-bottom: 30px;
|
|
|
|
|
margin-top: 15px;
|
|
|
|
|
font-weight: 300;
|
|
|
|
|
letter-spacing: 0.5px;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const ThemeSelectWrapper = styled.div`
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
width: 70%;
|
|
|
|
|
max-width: 600px;
|
|
|
|
|
min-width: 350px;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const SettingsActionWrapper = styled.div`
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
type Key = {
|
|
|
|
@ -231,12 +283,17 @@ export class SettingsView extends PureComponent<Props, State> {
|
|
|
|
|
/>
|
|
|
|
|
</ThemeSelectWrapper>
|
|
|
|
|
<ConfirmDialogComponent
|
|
|
|
|
title='Export View Keys'
|
|
|
|
|
title={EXPORT_VIEW_KEYS_TITLE}
|
|
|
|
|
renderTrigger={toggleVisibility => (
|
|
|
|
|
<SettingsWrapper>
|
|
|
|
|
<SettingsTitle value='Export View Keys' />
|
|
|
|
|
<SettingsContent value='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.' />
|
|
|
|
|
<Btn label='Export View Keys' onClick={toggleVisibility} />
|
|
|
|
|
<SettingsTitle value={EXPORT_VIEW_KEYS_TITLE} />
|
|
|
|
|
<SettingsContent value={EXPORT_VIEW_KEYS_CONTENT} />
|
|
|
|
|
<SettingsActionWrapper>
|
|
|
|
|
<Btn label={EXPORT_VIEW_KEYS_TITLE} onClick={toggleVisibility} />
|
|
|
|
|
<LearnMore onClick={() => openExternal(EXPORT_VIEW_KEYS_LEARN_MORE)}>
|
|
|
|
|
Learn More
|
|
|
|
|
</LearnMore>
|
|
|
|
|
</SettingsActionWrapper>
|
|
|
|
|
</SettingsWrapper>
|
|
|
|
|
)}
|
|
|
|
|
onConfirm={this.exportViewKeys}
|
|
|
|
@ -267,78 +324,79 @@ export class SettingsView extends PureComponent<Props, State> {
|
|
|
|
|
)}
|
|
|
|
|
</ConfirmDialogComponent>
|
|
|
|
|
|
|
|
|
|
<ConfirmDialogComponent
|
|
|
|
|
title='Export Private Keys'
|
|
|
|
|
renderTrigger={toggleVisibility => (
|
|
|
|
|
<SettingsWrapper>
|
|
|
|
|
<SettingsTitle value='Export Private Keys' />
|
|
|
|
|
<SettingsContent value='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.' />
|
|
|
|
|
<Btn label='Export Private Keys' onClick={toggleVisibility} />
|
|
|
|
|
</SettingsWrapper>
|
|
|
|
|
)}
|
|
|
|
|
onConfirm={this.exportPrivateKeys}
|
|
|
|
|
showButtons={!successExportPrivateKeys}
|
|
|
|
|
width={450}
|
|
|
|
|
>
|
|
|
|
|
{() => (
|
|
|
|
|
<ModalContent>
|
|
|
|
|
{successExportPrivateKeys ? (
|
|
|
|
|
privateKeys.map(({ zAddress, key }) => (
|
|
|
|
|
<>
|
|
|
|
|
<InputLabelComponent value={zAddress} />
|
|
|
|
|
<RowComponent alignItems='center'>
|
|
|
|
|
<InputComponent
|
|
|
|
|
value={key}
|
|
|
|
|
onFocus={(event) => {
|
|
|
|
|
event.currentTarget.select();
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<ClipboardButton text={key} />
|
|
|
|
|
</RowComponent>
|
|
|
|
|
</>
|
|
|
|
|
))
|
|
|
|
|
) : (
|
|
|
|
|
<TextComponent value='Ut id vulputate arcu. Curabitur mattis aliquam magna sollicitudin vulputate. Morbi tempus bibendum porttitor. Quisque dictum ac ipsum a luctus. Donec et lacus ac erat consectetur molestie a id erat.' />
|
|
|
|
|
)}
|
|
|
|
|
</ModalContent>
|
|
|
|
|
)}
|
|
|
|
|
</ConfirmDialogComponent>
|
|
|
|
|
|
|
|
|
|
<ConfirmDialogComponent
|
|
|
|
|
title='Import Private Keys'
|
|
|
|
|
renderTrigger={toggleVisibility => (
|
|
|
|
|
<SettingsWrapper>
|
|
|
|
|
<SettingsTitle value='Import Private Keys' />
|
|
|
|
|
<SettingsContent value='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.' />
|
|
|
|
|
<Btn label='Import Private Keys' onClick={toggleVisibility} />
|
|
|
|
|
</SettingsWrapper>
|
|
|
|
|
)}
|
|
|
|
|
onConfirm={this.importPrivateKeys}
|
|
|
|
|
showButtons={!successImportPrivateKeys}
|
|
|
|
|
width={450}
|
|
|
|
|
isLoading={isLoading}
|
|
|
|
|
>
|
|
|
|
|
{() => (
|
|
|
|
|
<ModalContent>
|
|
|
|
|
<InputLabelComponent value='Please paste your private keys here, one per line. The keys will be imported into your zcashd node' />
|
|
|
|
|
<InputComponent
|
|
|
|
|
value={importedPrivateKeys}
|
|
|
|
|
onChange={value => this.setState({ importedPrivateKeys: value })}
|
|
|
|
|
inputType='textarea'
|
|
|
|
|
rows={10}
|
|
|
|
|
/>
|
|
|
|
|
{successImportPrivateKeys && (
|
|
|
|
|
<TextComponent value='Private keys imported in your node' align='center' />
|
|
|
|
|
)}
|
|
|
|
|
{error && <TextComponent value={error} align='center' />}
|
|
|
|
|
</ModalContent>
|
|
|
|
|
)}
|
|
|
|
|
</ConfirmDialogComponent>
|
|
|
|
|
<SettingsWrapper>
|
|
|
|
|
<ConfirmDialogComponent
|
|
|
|
|
title={EXPORT_PRIV_KEYS_TITLE}
|
|
|
|
|
renderTrigger={toggleVisibility => (
|
|
|
|
|
<SettingsInnerWrapper>
|
|
|
|
|
<SettingsTitle value={EXPORT_PRIV_KEYS_TITLE} />
|
|
|
|
|
<SettingsContent value={EXPORT_PRIV_KEYS_CONTENT} />
|
|
|
|
|
<Btn label={EXPORT_PRIV_KEYS_TITLE} onClick={toggleVisibility} />
|
|
|
|
|
</SettingsInnerWrapper>
|
|
|
|
|
)}
|
|
|
|
|
onConfirm={this.exportPrivateKeys}
|
|
|
|
|
showButtons={!successExportPrivateKeys}
|
|
|
|
|
width={450}
|
|
|
|
|
>
|
|
|
|
|
{() => (
|
|
|
|
|
<ModalContent>
|
|
|
|
|
{successExportPrivateKeys ? (
|
|
|
|
|
privateKeys.map(({ zAddress, key }) => (
|
|
|
|
|
<>
|
|
|
|
|
<InputLabelComponent value={zAddress} />
|
|
|
|
|
<RowComponent alignItems='center'>
|
|
|
|
|
<InputComponent
|
|
|
|
|
value={key}
|
|
|
|
|
onFocus={(event) => {
|
|
|
|
|
event.currentTarget.select();
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<ClipboardButton text={key} />
|
|
|
|
|
</RowComponent>
|
|
|
|
|
</>
|
|
|
|
|
))
|
|
|
|
|
) : (
|
|
|
|
|
<TextComponent value='Ut id vulputate arcu. Curabitur mattis aliquam magna sollicitudin vulputate. Morbi tempus bibendum porttitor. Quisque dictum ac ipsum a luctus. Donec et lacus ac erat consectetur molestie a id erat.' />
|
|
|
|
|
)}
|
|
|
|
|
</ModalContent>
|
|
|
|
|
)}
|
|
|
|
|
</ConfirmDialogComponent>
|
|
|
|
|
<ConfirmDialogComponent
|
|
|
|
|
title={IMPORT_PRIV_KEYS_TITLE}
|
|
|
|
|
renderTrigger={toggleVisibility => (
|
|
|
|
|
<SettingsInnerWrapper>
|
|
|
|
|
<SettingsTitle value={IMPORT_PRIV_KEYS_TITLE} />
|
|
|
|
|
<SettingsContent value={IMPORT_PRIV_KEYS_CONTENT} />
|
|
|
|
|
<Btn label={IMPORT_PRIV_KEYS_TITLE} onClick={toggleVisibility} />
|
|
|
|
|
</SettingsInnerWrapper>
|
|
|
|
|
)}
|
|
|
|
|
onConfirm={this.importPrivateKeys}
|
|
|
|
|
showButtons={!successImportPrivateKeys}
|
|
|
|
|
width={450}
|
|
|
|
|
isLoading={isLoading}
|
|
|
|
|
>
|
|
|
|
|
{() => (
|
|
|
|
|
<ModalContent>
|
|
|
|
|
<InputLabelComponent value='Please paste your private keys here, one per line. The keys will be imported into your zcashd node' />
|
|
|
|
|
<InputComponent
|
|
|
|
|
value={importedPrivateKeys}
|
|
|
|
|
onChange={value => this.setState({ importedPrivateKeys: value })}
|
|
|
|
|
inputType='textarea'
|
|
|
|
|
rows={10}
|
|
|
|
|
/>
|
|
|
|
|
{successImportPrivateKeys && (
|
|
|
|
|
<TextComponent value='Private keys imported in your node' align='center' />
|
|
|
|
|
)}
|
|
|
|
|
{error && <TextComponent value={error} align='center' />}
|
|
|
|
|
</ModalContent>
|
|
|
|
|
)}
|
|
|
|
|
</ConfirmDialogComponent>
|
|
|
|
|
</SettingsWrapper>
|
|
|
|
|
|
|
|
|
|
<SettingsWrapper>
|
|
|
|
|
<SettingsTitle value='Backup Wallet' />
|
|
|
|
|
<SettingsContent value='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.' />
|
|
|
|
|
<Btn label='Backup Wallet' onClick={this.backupWalletDat} />
|
|
|
|
|
<SettingsTitle value={BACKUP_WALLET_TITLE} />
|
|
|
|
|
<SettingsContent value={BACKUP_WALLET_CONTENT} />
|
|
|
|
|
<Btn label={BACKUP_WALLET_TITLE} onClick={this.backupWalletDat} />
|
|
|
|
|
</SettingsWrapper>
|
|
|
|
|
</Wrapper>
|
|
|
|
|
);
|
|
|
|
|