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