diff --git a/packages/extension-base/src/background/handlers/Extension.ts b/packages/extension-base/src/background/handlers/Extension.ts index 8d764f3e..f198daea 100644 --- a/packages/extension-base/src/background/handlers/Extension.ts +++ b/packages/extension-base/src/background/handlers/Extension.ts @@ -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, diff --git a/packages/extension-base/src/background/types.ts b/packages/extension-base/src/background/types.ts index 85214767..2236e989 100644 --- a/packages/extension-base/src/background/types.ts +++ b/packages/extension-base/src/background/types.ts @@ -297,6 +297,7 @@ export type RequestSigningSubscribe = null; export interface RequestSeedCreate { length?: SeedLengths; + seed?: string; type?: KeypairType; } diff --git a/packages/extension-ui/src/Popup/ImportQr.tsx b/packages/extension-ui/src/Popup/ImportQr.tsx index 1d4e4a88..c691c210 100644 --- a/packages/extension-ui/src/Popup/ImportQr.tsx +++ b/packages/extension-ui/src/Popup/ImportQr.tsx @@ -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(null); + const [address, setAddress] = useState(null); const [name, setName] = useState(null); + const [password, setPassword] = useState(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 {
- + {account.isAddress + ? ( + + ) + : ( + + ) + } {t('Add the account with identified address')} diff --git a/packages/extension-ui/src/components/AccountNamePasswordCreation.tsx b/packages/extension-ui/src/components/AccountNamePasswordCreation.tsx index 89a422a4..5ebacce7 100644 --- a/packages/extension-ui/src/components/AccountNamePasswordCreation.tsx +++ b/packages/extension-ui/src/components/AccountNamePasswordCreation.tsx @@ -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; onNameChange: (name: string) => void; + onPasswordChange?: (password: string) => void; } -function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCreate, onNameChange }: Props): React.ReactElement { +function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCreate, onNameChange, onPasswordChange }: Props): React.ReactElement { const [name, setName] = useState(null); const [password, setPassword] = useState(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} /> - + - - - - {buttonLabel} - - + {onBackClick && buttonLabel && ( + + + + {buttonLabel} + + + )} ); } diff --git a/packages/extension-ui/src/messaging.ts b/packages/extension-ui/src/messaging.ts index 171dd8d6..a41b808f 100644 --- a/packages/extension-ui/src/messaging.ts +++ b/packages/extension-ui/src/messaging.ts @@ -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 {