Allow for creation via QR seed (#918)
This commit is contained in:
parent
4e98ce540e
commit
9e9911dc8a
@ -304,8 +304,8 @@ export default class Extension {
|
||||
}
|
||||
}
|
||||
|
||||
private seedCreate ({ length = SEED_DEFAULT_LENGTH, type }: RequestSeedCreate): ResponseSeedCreate {
|
||||
const seed = mnemonicGenerate(length);
|
||||
private seedCreate ({ length = SEED_DEFAULT_LENGTH, seed: _seed, type }: RequestSeedCreate): ResponseSeedCreate {
|
||||
const seed = _seed || mnemonicGenerate(length);
|
||||
|
||||
return {
|
||||
address: keyring.createFromUri(getSuri(seed, type), {}, type).address,
|
||||
|
||||
@ -297,6 +297,7 @@ export type RequestSigningSubscribe = null;
|
||||
|
||||
export interface RequestSeedCreate {
|
||||
length?: SeedLengths;
|
||||
seed?: string;
|
||||
type?: KeypairType;
|
||||
}
|
||||
|
||||
|
||||
@ -6,13 +6,15 @@ import React, { useCallback, useContext, useState } from 'react';
|
||||
import { QrScanAddress } from '@polkadot/react-qr';
|
||||
|
||||
import { ActionContext, Address, ButtonArea, NextStepButton, VerticalSpace } from '../components';
|
||||
import AccountNamePasswordCreation from '../components/AccountNamePasswordCreation';
|
||||
import useTranslation from '../hooks/useTranslation';
|
||||
import { createAccountExternal } from '../messaging';
|
||||
import { createAccountExternal, createAccountSuri, createSeed } from '../messaging';
|
||||
import { Header, Name } from '../partials';
|
||||
|
||||
interface QrAccount {
|
||||
content: string;
|
||||
genesisHash: string;
|
||||
isAddress: boolean;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
@ -20,12 +22,22 @@ export default function ImportQr (): React.ReactElement {
|
||||
const { t } = useTranslation();
|
||||
const onAction = useContext(ActionContext);
|
||||
const [account, setAccount] = useState<QrAccount | null>(null);
|
||||
const [address, setAddress] = useState<string | null>(null);
|
||||
const [name, setName] = useState<string | null>(null);
|
||||
const [password, setPassword] = useState<string | null>(null);
|
||||
|
||||
const _setAccount = useCallback(
|
||||
(qrAccount: QrAccount) => {
|
||||
setAccount(qrAccount);
|
||||
setName(qrAccount?.name || null);
|
||||
|
||||
if (qrAccount.isAddress) {
|
||||
setAddress(qrAccount.content);
|
||||
} else {
|
||||
createSeed(undefined, qrAccount.content)
|
||||
.then(({ address }) => setAddress(address))
|
||||
.catch(console.error);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
@ -33,12 +45,18 @@ export default function ImportQr (): React.ReactElement {
|
||||
const _onCreate = useCallback(
|
||||
(): void => {
|
||||
if (account && name) {
|
||||
createAccountExternal(name, account.content, account.genesisHash)
|
||||
.then(() => onAction('/'))
|
||||
.catch((error: Error) => console.error(error));
|
||||
if (account.isAddress) {
|
||||
createAccountExternal(name, account.content, account.genesisHash)
|
||||
.then(() => onAction('/'))
|
||||
.catch((error: Error) => console.error(error));
|
||||
} else if (password) {
|
||||
createAccountSuri(name, password, account.content, 'sr25519', account.genesisHash)
|
||||
.then(() => onAction('/'))
|
||||
.catch((error: Error) => console.error(error));
|
||||
}
|
||||
}
|
||||
},
|
||||
[account, name, onAction]
|
||||
[account, name, onAction, password]
|
||||
);
|
||||
|
||||
return (
|
||||
@ -57,20 +75,32 @@ export default function ImportQr (): React.ReactElement {
|
||||
<div>
|
||||
<Address
|
||||
{...account}
|
||||
address={account.content}
|
||||
address={address}
|
||||
isExternal={true}
|
||||
name={name}
|
||||
/>
|
||||
</div>
|
||||
<Name
|
||||
isFocused
|
||||
onChange={setName}
|
||||
value={name || ''}
|
||||
/>
|
||||
{account.isAddress
|
||||
? (
|
||||
<Name
|
||||
isFocused
|
||||
onChange={setName}
|
||||
value={name || ''}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<AccountNamePasswordCreation
|
||||
isBusy={false}
|
||||
onCreate={_onCreate}
|
||||
onNameChange={setName}
|
||||
onPasswordChange={setPassword}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<VerticalSpace />
|
||||
<ButtonArea>
|
||||
<NextStepButton
|
||||
isDisabled={!name}
|
||||
isDisabled={!name || (!account.isAddress && !password)}
|
||||
onClick={_onCreate}
|
||||
>
|
||||
{t<string>('Add the account with identified address')}
|
||||
|
||||
@ -7,14 +7,15 @@ import { Name, Password } from '../partials';
|
||||
import { BackButton, ButtonArea, NextStepButton, VerticalSpace } from '.';
|
||||
|
||||
interface Props {
|
||||
buttonLabel: string;
|
||||
buttonLabel?: string;
|
||||
isBusy: boolean;
|
||||
onBackClick: () => void;
|
||||
onBackClick?: () => void;
|
||||
onCreate: (name: string, password: string) => void | Promise<void | boolean>;
|
||||
onNameChange: (name: string) => void;
|
||||
onPasswordChange?: (password: string) => void;
|
||||
}
|
||||
|
||||
function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCreate, onNameChange }: Props): React.ReactElement<Props> {
|
||||
function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCreate, onNameChange, onPasswordChange }: Props): React.ReactElement<Props> {
|
||||
const [name, setName] = useState<string | null>(null);
|
||||
const [password, setPassword] = useState<string | null>(null);
|
||||
|
||||
@ -31,11 +32,19 @@ function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCrea
|
||||
[onNameChange]
|
||||
);
|
||||
|
||||
const _onPasswordChange = useCallback(
|
||||
(password: string | null) => {
|
||||
onPasswordChange && onPasswordChange(password || '');
|
||||
setPassword(password);
|
||||
},
|
||||
[onPasswordChange]
|
||||
);
|
||||
|
||||
const _onBackClick = useCallback(
|
||||
() => {
|
||||
_onNameChange(null);
|
||||
setPassword(null);
|
||||
onBackClick();
|
||||
onBackClick && onBackClick();
|
||||
},
|
||||
[_onNameChange, onBackClick]
|
||||
);
|
||||
@ -46,19 +55,21 @@ function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCrea
|
||||
isFocused
|
||||
onChange={_onNameChange}
|
||||
/>
|
||||
<Password onChange={setPassword} />
|
||||
<Password onChange={_onPasswordChange} />
|
||||
<VerticalSpace />
|
||||
<ButtonArea>
|
||||
<BackButton onClick={_onBackClick} />
|
||||
<NextStepButton
|
||||
data-button-action='add new root'
|
||||
isBusy={isBusy}
|
||||
isDisabled={!password || !name}
|
||||
onClick={_onCreate}
|
||||
>
|
||||
{buttonLabel}
|
||||
</NextStepButton>
|
||||
</ButtonArea>
|
||||
{onBackClick && buttonLabel && (
|
||||
<ButtonArea>
|
||||
<BackButton onClick={_onBackClick} />
|
||||
<NextStepButton
|
||||
data-button-action='add new root'
|
||||
isBusy={isBusy}
|
||||
isDisabled={!password || !name}
|
||||
onClick={_onCreate}
|
||||
>
|
||||
{buttonLabel}
|
||||
</NextStepButton>
|
||||
</ButtonArea>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -132,8 +132,8 @@ export async function createAccountSuri (name: string, password: string, suri: s
|
||||
return sendMessage('pri(accounts.create.suri)', { genesisHash, name, password, suri, type });
|
||||
}
|
||||
|
||||
export async function createSeed (length?: SeedLengths, type?: KeypairType): Promise<{ address: string; seed: string }> {
|
||||
return sendMessage('pri(seed.create)', { length, type });
|
||||
export async function createSeed (length?: SeedLengths, seed?: string, type?: KeypairType): Promise<{ address: string; seed: string }> {
|
||||
return sendMessage('pri(seed.create)', { length, seed, type });
|
||||
}
|
||||
|
||||
export async function getAllMetatdata (): Promise<MetadataDef[]> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user