diff --git a/packages/app-toolbox/src/Verify.tsx b/packages/app-toolbox/src/Verify.tsx index c596d6b3dd..9d889537e4 100644 --- a/packages/app-toolbox/src/Verify.tsx +++ b/packages/app-toolbox/src/Verify.tsx @@ -5,7 +5,7 @@ import { I18nProps as Props } from '@polkadot/react-components/types'; import { KeypairType } from '@polkadot/util-crypto/types'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Dropdown, Icon, Input, InputAddress, Static } from '@polkadot/react-components'; import keyring from '@polkadot/ui-keyring'; import uiSettings from '@polkadot/ui-settings'; @@ -17,211 +17,145 @@ import translate from './translate'; type CryptoTypes = KeypairType | 'unknown'; -interface CryptoOption { - text: string; - value: string; -} - -interface State { - currentPublicKey: Uint8Array | null; - cryptoOptions: CryptoOption[]; - cryptoType: CryptoTypes; - defaultPublicKey?: Uint8Array; - data: string; - isHexData: boolean; - isValidAddress: boolean; - isValidSignature: boolean; - isValid: boolean; - signature: string; -} - const AlignedIcon = styled(Icon)` &&&::before { position: relative; left: 0.88rem; - top: 1rem; + top: 1rem; width: 32px; height: 32px; font-size: 32px; background: white !important; border-radius: 50%; } - + &&&.big.icon { font-size: 32px; } `; -class Verify extends React.PureComponent { - public state: State; +function Verify ({ t }: Props): React.ReactElement { + const [{ cryptoType, isValid }, setValidity] = useState<{ cryptoType: CryptoTypes; isValid: boolean }>({ cryptoType: 'unknown', isValid: false }); + const [{ data, isHexData }, setData] = useState<{ data: string; isHexData: boolean }>({ data: '', isHexData: false }); + const [{ publicKey, isValidPk }, setPublicKey] = useState<{ publicKey: Uint8Array | null; isValidPk: boolean }>({ publicKey: null, isValidPk: false }); + const [{ signature, isValidSignature }, setSignature] = useState<{ signature: string; isValidSignature: boolean }>({ signature: '', isValidSignature: false }); + const [cryptoOptions] = useState([{ value: 'unknown', text: t('Crypto not detected') }].concat(uiSettings.availableCryptos as any[])); - public constructor (props: Props) { - super(props); + useEffect((): void => { + let cryptoType: CryptoTypes = 'unknown'; + let isValid = isValidPk && isValidSignature; - const { t } = this.props; - const pairs = keyring.getPairs(); - const currentPair = pairs[0]; - const currentPublicKey = currentPair - ? currentPair.publicKey - : null; + // We cannot just use the keyring verify since it may be an address. So here we first check + // for ed25519, if not valid, we try against sr25519 - if neither are valid, well, we have + // not been able to validate the signature + if (isValid && publicKey) { + let isValidSr = false; + let isValidEd = false; - this.state = { - cryptoOptions: [{ value: 'unknown', text: t('Crypto not detected') }].concat(uiSettings.availableCryptos as any[]), - cryptoType: 'unknown', - currentPublicKey, - defaultPublicKey: currentPublicKey || undefined, - data: '', - isHexData: false, - isValidAddress: !!currentPair, - isValidSignature: false, - isValid: false, - signature: '' - }; - } + try { + isValidEd = naclVerify(data, signature, publicKey); + } catch (error) { + // do nothing, already set to false + } - public render (): React.ReactNode { - const { t } = this.props; - const { cryptoOptions, cryptoType, data, defaultPublicKey, isHexData, isValid, isValidAddress, isValidSignature, signature } = this.state; - - return ( -
-
- -
-
- -
-
-
- -
- -
-
- - -
-
- ); - } - - private nextState (newState: Partial): void { - this.setState( - (prevState: State): Pick => { - const { isHexData = prevState.isHexData, isValidAddress = prevState.isValidAddress, isValidSignature = prevState.isValidSignature, currentPublicKey = prevState.currentPublicKey, data = prevState.data, signature = prevState.signature } = newState; - let cryptoType: CryptoTypes = 'unknown'; - let isValid = isValidAddress && isValidSignature; - - // We cannot just use the keyring verify since it may be an address. So here we first check - // for ed25519, if not valid, we try against sr25519 - if neither are valid, well, we have - // not been able to validate the signature - if (isValid && currentPublicKey) { - let isValidSr = false; - let isValidEd = false; - - try { - isValidEd = naclVerify(data, signature, currentPublicKey); - } catch (error) { - // do nothing, already set to false - } - - if (isValidEd) { - cryptoType = 'ed25519'; - } else { - try { - isValidSr = schnorrkelVerify(data, signature, currentPublicKey); - } catch (error) { - // do nothing, already set to false - } - - if (isValidSr) { - cryptoType = 'sr25519'; - } else { - isValid = false; - } - } + if (isValidEd) { + cryptoType = 'ed25519'; + } else { + try { + isValidSr = schnorrkelVerify(data, signature, publicKey); + } catch (error) { + // do nothing, already set to false } - return { - cryptoType, - isHexData, - isValid, - isValidAddress, - isValidSignature, - currentPublicKey, - data, - signature - }; + if (isValidSr) { + cryptoType = 'sr25519'; + } else { + isValid = false; + } } - ); - } + } - private onChangeData = (data: string): void => { - const isHexData = isHex(data); + setValidity({ cryptoType, isValid }); + }, [data, isValidPk, isValidSignature, publicKey, signature]); - this.nextState({ data, isHexData }); - } - - private onChangeSignature = (signature: string): void => { - const isValidSignature = isHex(signature) && signature.length === 130; - - this.nextState({ signature, isValidSignature }); - } - - private onChangeAddress = (accountId: string | null): void => { - let currentPublicKey; + const _onChangeAddress = (accountId: string | null): void => { + let publicKey: Uint8Array | null = null; try { - currentPublicKey = keyring.decodeAddress(accountId || ''); + publicKey = keyring.decodeAddress(accountId || ''); } catch (err) { console.error(err); } - const isValidAddress = currentPublicKey && currentPublicKey.length === 32; + setPublicKey({ publicKey, isValidPk: !!publicKey && publicKey.length === 32 }); + }; - this.nextState({ currentPublicKey, isValidAddress }); - } + const _onChangeData = (data: string): void => + setData({ data, isHexData: isHex(data) }); + + const _onChangeSignature = (signature: string): void => + setSignature({ signature, isValidSignature: isHex(signature) && signature.length === 130 }); + + return ( +
+
+ +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+ ); } export default translate(Verify);