Derive path for eth derivation (#4732)
* derivae path for eth derivation * remove consoles * lint * Apply suggestions from code review Co-authored-by: Jaco Greeff <jacogr@gmail.com> * applied suggestions * lint and modifs * Apply suggestions from code review thanks for the suggestions! Co-authored-by: Jaco Greeff <jacogr@gmail.com> * Apply suggestions from code review Co-authored-by: Jaco Greeff <jacogr@gmail.com> * more suggestions and cleaning" Co-authored-by: Jaco Greeff <jacogr@gmail.com>
This commit is contained in:
parent
c9d262a382
commit
199c9a3dfb
@ -17,7 +17,7 @@ import { useApi, useLedger, useStepper } from '@polkadot/react-hooks';
|
||||
import { keyring } from '@polkadot/ui-keyring';
|
||||
import { settings } from '@polkadot/ui-settings';
|
||||
import { isHex, u8aToHex } from '@polkadot/util';
|
||||
import { hdLedger, keyExtractSuri, mnemonicGenerate, mnemonicValidate, randomAsU8a } from '@polkadot/util-crypto';
|
||||
import { hdLedger, hdValidatePath, keyExtractSuri, mnemonicGenerate, mnemonicValidate, randomAsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import CreateConfirmation from './CreateConfirmation';
|
||||
@ -25,6 +25,8 @@ import CreateSuriLedger from './CreateSuriLedger';
|
||||
import ExternalWarning from './ExternalWarning';
|
||||
import PasswordInput from './PasswordInput';
|
||||
|
||||
const ETH_DEFAULT_PATH = "m/44'/60'/0'/0/0";
|
||||
|
||||
type PairType = 'ecdsa' | 'ed25519' | 'ed25519-ledger' | 'ethereum' | 'sr25519';
|
||||
|
||||
interface Props extends ModalProps {
|
||||
@ -64,12 +66,14 @@ const STEPS_COUNT = 3;
|
||||
function getSuri (seed: string, derivePath: string, pairType: PairType): string {
|
||||
return pairType === 'ed25519-ledger'
|
||||
? u8aToHex(hdLedger(seed, derivePath).secretKey.slice(0, 32))
|
||||
: `${seed}${derivePath}`;
|
||||
: pairType === 'ethereum'
|
||||
? `${seed}/${derivePath}`
|
||||
: `${seed}${derivePath}`;
|
||||
}
|
||||
|
||||
function deriveValidate (seed: string, seedType: SeedType, derivePath: string, pairType: PairType): DeriveValidationOutput {
|
||||
try {
|
||||
const { password, path } = keyExtractSuri(`${seed}${derivePath}`);
|
||||
const { password, path } = keyExtractSuri(pairType === 'ethereum' ? `${seed}/${derivePath}` : `${seed}${derivePath}`);
|
||||
let result: DeriveValidationOutput = {};
|
||||
|
||||
// show a warning in case the password contains an unintended / character
|
||||
@ -87,6 +91,10 @@ function deriveValidate (seed: string, seedType: SeedType, derivePath: string, p
|
||||
return { ...result, error: 'PASSWORD_IGNORED' };
|
||||
}
|
||||
|
||||
if (pairType === 'ethereum' && !hdValidatePath(derivePath)) {
|
||||
return { ...result, error: 'INVALID_DERIVATION_PATH' };
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { error: (error as Error).message };
|
||||
@ -134,19 +142,18 @@ function generateSeed (_seed: string | undefined | null, derivePath: string, see
|
||||
}
|
||||
|
||||
function updateAddress (seed: string, derivePath: string, seedType: SeedType, pairType: PairType): AddressState {
|
||||
const deriveValidation = deriveValidate(seed, seedType, derivePath, pairType);
|
||||
|
||||
let address: string | null = null;
|
||||
let deriveValidation: DeriveValidationOutput = deriveValidate(seed, seedType, derivePath, pairType);
|
||||
let isSeedValid = seedType === 'raw'
|
||||
? rawValidate(seed)
|
||||
: mnemonicValidate(seed);
|
||||
let address: string | null = null;
|
||||
|
||||
if (!deriveValidation?.error && isSeedValid) {
|
||||
try {
|
||||
address = addressFromSeed(seed, derivePath, pairType);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
deriveValidation = { error: (error as Error).message ? (error as Error).message : (error as Error).toString() };
|
||||
isSeedValid = false;
|
||||
}
|
||||
}
|
||||
@ -197,7 +204,11 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
|
||||
const { t } = useTranslation();
|
||||
const { api, isDevelopment, isEthereum } = useApi();
|
||||
const { isLedgerEnabled } = useLedger();
|
||||
const [{ address, derivePath, deriveValidation, isSeedValid, pairType, seed, seedType }, setAddress] = useState<AddressState>(() => generateSeed(propsSeed, '', propsSeed ? 'raw' : 'bip', isEthereum ? 'ethereum' : propsType));
|
||||
const [{ address, derivePath, deriveValidation, isSeedValid, pairType, seed, seedType }, setAddress] = useState<AddressState>(() => generateSeed(
|
||||
propsSeed,
|
||||
isEthereum ? ETH_DEFAULT_PATH : '',
|
||||
propsSeed ? 'raw' : 'bip', isEthereum ? 'ethereum' : propsType
|
||||
));
|
||||
const [isMnemonicSaved, setIsMnemonicSaved] = useState<boolean>(false);
|
||||
const [step, nextStep, prevStep] = useStepper();
|
||||
const [isBusy, setIsBusy] = useState(false);
|
||||
@ -208,6 +219,7 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
|
||||
const isValid = isFirstStepValid && isSecondStepValid;
|
||||
|
||||
const errorIndex = useRef<Record<string, string>>({
|
||||
INVALID_DERIVATION_PATH: t<string>('This is an invalid derivation path.'),
|
||||
PASSWORD_IGNORED: t<string>('Password are ignored for hex seed'),
|
||||
SOFT_NOT_ALLOWED: t<string>('Soft derivation paths are not allowed on ed25519'),
|
||||
WARNING_SLASH_PASSWORD: t<string>('Your password contains at least one "/" character. Disregard this warning if it is intended.')
|
||||
@ -240,9 +252,9 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
|
||||
|
||||
const _onChangePairType = useCallback(
|
||||
(newPairType: PairType) => setAddress(
|
||||
updateAddress(seed, '', seedType, newPairType)
|
||||
updateAddress(seed, isEthereum ? ETH_DEFAULT_PATH : '', seedType, newPairType)
|
||||
),
|
||||
[seed, seedType]
|
||||
[seed, seedType, isEthereum]
|
||||
);
|
||||
|
||||
const _selectSeedType = useCallback(
|
||||
@ -387,13 +399,15 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
|
||||
label={t<string>('secret derivation path')}
|
||||
onChange={_onChangePath}
|
||||
placeholder={
|
||||
seedType === 'raw'
|
||||
? pairType === 'sr25519'
|
||||
? t<string>('//hard/soft')
|
||||
: t<string>('//hard')
|
||||
: pairType === 'sr25519'
|
||||
? t<string>('//hard/soft///password')
|
||||
: t<string>('//hard///password')
|
||||
pairType === 'ethereum'
|
||||
? ETH_DEFAULT_PATH
|
||||
: seedType === 'raw'
|
||||
? pairType === 'sr25519'
|
||||
? t<string>('//hard/soft')
|
||||
: t<string>('//hard')
|
||||
: pairType === 'sr25519'
|
||||
? t<string>('//hard/soft///password')
|
||||
: t<string>('//hard///password')
|
||||
}
|
||||
tabIndex={-1}
|
||||
value={derivePath}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user