ghost-portal/packages/app-staking/src/Actions/Account/InjectKeys.tsx
Jaco Greeff 8e971ef7eb
Use ButtonCancel for all Cancel-only buttons (#2164)
* Use ButtonCancel for all Cancel-only buttons

* Small cleanups
2020-01-21 15:47:44 +01:00

129 lines
3.8 KiB
TypeScript

// Copyright 2017-2020 @polkadot/app-staking authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/react-components/types';
import { KeypairType } from '@polkadot/util-crypto/types';
import React, { useContext, useEffect, useState } from 'react';
import { Button, ButtonCancel, Dropdown, Icon, Input, Modal, StatusContext } from '@polkadot/react-components';
import keyring from '@polkadot/ui-keyring';
import { assert, u8aToHex } from '@polkadot/util';
import { keyExtractSuri, mnemonicValidate } from '@polkadot/util-crypto';
import translate from '../../translate';
interface Props extends I18nProps {
isOpen?: boolean;
onClose: () => void;
}
const CRYPTO_MAP: Record<string, KeypairType[]> = {
aura: ['ed25519', 'sr25519'],
babe: ['sr25519'],
gran: ['ed25519'],
imon: ['ed25519', 'sr25519'],
para: ['sr25519']
};
const EMPTY_KEY = '0x';
function InjectKeys ({ isOpen = true, onClose, t }: Props): React.ReactElement<Props> | null {
const { queueRpc } = useContext(StatusContext);
// this needs to align with what is set as the first value in `type`
const [crypto, setCrypto] = useState<KeypairType>('sr25519');
const [publicKey, setPublicKey] = useState(EMPTY_KEY);
const [suri, setSuri] = useState('');
const [type, setType] = useState('babe');
useEffect((): void => {
setCrypto(CRYPTO_MAP[type][0]);
}, [type]);
useEffect((): void => {
try {
const { phrase } = keyExtractSuri(suri);
assert(mnemonicValidate(phrase), 'Invalid mnemonic phrase');
setPublicKey(u8aToHex(keyring.createFromUri(suri, {}, crypto).publicKey));
} catch (error) {
setPublicKey(EMPTY_KEY);
}
}, [crypto, suri]);
if (!isOpen) {
return null;
}
const _onSubmit = (): void => {
queueRpc({
rpc: { section: 'author', method: 'insertKey' } as any,
values: [type, suri, publicKey]
});
};
const _cryptoOptions = CRYPTO_MAP[type].map((value): { text: string; value: KeypairType } => ({
text: value === 'ed25519'
? t('ed25519, Edwards')
: t('sr15519, Schnorrkel'),
value
}));
return (
<Modal
header={t('Inject Keys')}
size='small'
>
<Modal.Content>
<Input
isError={publicKey.length !== 66}
label={t('suri (seed & derivation)')}
onChange={setSuri}
value={suri}
/>
<Dropdown
label={t('key type to set')}
onChange={setType}
options={[
{ text: t('Aura'), value: 'aura' },
{ text: t('Babe'), value: 'babe' },
{ text: t('Grandpa'), value: 'gran' },
{ text: t('I\'m Online'), value: 'imon' },
{ text: t('Parachains'), value: 'para' }
]}
value={type}
/>
<Dropdown
isDisabled={_cryptoOptions.length === 1}
label={t('crypto type to use')}
onChange={setCrypto}
options={_cryptoOptions}
value={crypto}
/>
<Input
isDisabled
label={t('generated public key')}
value={publicKey}
/>
<article className='warning'>
<div><Icon name='warning sign' />{t('This operation will submit the seed via an RPC call. Do not perform this operation on a public RPC node, but ensure that the node is local, connected to your validator and secure.')}</div>
</article>
</Modal.Content>
<Modal.Actions>
<Button.Group>
<ButtonCancel onClick={onClose} />
<Button.Or />
<Button
icon='sign-in'
isPrimary
label={t('Submit key')}
onClick={_onSubmit}
/>
</Button.Group>
</Modal.Actions>
</Modal>
);
}
export default translate(InjectKeys);