Add network selector when importing an account with mnemonic, and refactor (#627)
* add network selector and refactor * fr trad that didnot apprear before * with useRef * font-size * nit still failing * and that work .. but not what I need * giving up on the test :(
This commit is contained in:
parent
153c691057
commit
2b9274c40f
@ -1,22 +0,0 @@
|
||||
// Copyright 2019-2021 @polkadot/extension-chains authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import chains from './chains';
|
||||
|
||||
interface Option {
|
||||
text: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const hashes: Option[] = [
|
||||
{
|
||||
text: 'Allow use on any chain',
|
||||
value: ''
|
||||
},
|
||||
...chains.map(({ chain, genesisHash }) => ({
|
||||
text: chain,
|
||||
value: genesisHash
|
||||
}))
|
||||
];
|
||||
|
||||
export default hashes;
|
||||
@ -10,7 +10,6 @@ import { base64Decode } from '@polkadot/util-crypto';
|
||||
|
||||
// imports chain details, generally metadata. For the generation of these,
|
||||
// inside the api, run `yarn chain:info --ws <url>`
|
||||
// import kusama from './kusama';
|
||||
|
||||
const definitions = new Map<string, MetadataDef>(
|
||||
// [kusama].map((def) => [def.genesisHash, def])
|
||||
|
||||
@ -7,9 +7,9 @@ import React, { useCallback, useContext, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { canDerive } from '@polkadot/extension-base/utils';
|
||||
import genesisOptions from '@polkadot/extension-chains/genesisHashes';
|
||||
|
||||
import { ActionContext, Address, Dropdown, Link, MenuDivider } from '../../components';
|
||||
import useGenesisHashOptions from '../../hooks/useGenesisHashOptions';
|
||||
import useTranslation from '../../hooks/useTranslation';
|
||||
import { editAccount, tieAccount } from '../../messaging';
|
||||
import { Name } from '../../partials';
|
||||
@ -29,6 +29,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
|
||||
const onAction = useContext(ActionContext);
|
||||
const [{ isEditing, toggleActions }, setEditing] = useState<EditState>({ isEditing: false, toggleActions: 0 });
|
||||
const [editedName, setName] = useState<string | null>(null);
|
||||
const genesisOptions = useGenesisHashOptions();
|
||||
|
||||
const _onChangeGenesis = useCallback(
|
||||
(genesisHash?: string | null): void => {
|
||||
@ -103,7 +104,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
), [_onChangeGenesis, _toggleEdit, address, genesisHash, isExternal, isHardware, t, type]);
|
||||
), [_onChangeGenesis, _toggleEdit, address, genesisHash, genesisOptions, isExternal, isHardware, t, type]);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -174,7 +174,7 @@ describe('ImportSeed', () => {
|
||||
await act(flushAllPromises);
|
||||
wrapper.update();
|
||||
|
||||
expect(messaging.createAccountSuri).toBeCalledWith(account.name, account.password, suri);
|
||||
expect(messaging.createAccountSuri).toBeCalledWith(account.name, account.password, suri, undefined, '');
|
||||
expect(onActionStub).toBeCalledWith('/');
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ThemeProps } from '../../types';
|
||||
import type { AccountInfo } from '.';
|
||||
|
||||
import { faCaretDown, faCaretRight } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
@ -10,27 +11,25 @@ import styled from 'styled-components';
|
||||
|
||||
import { validateSeed } from '@polkadot/extension-ui/messaging';
|
||||
|
||||
import { ButtonArea, InputWithLabel, NextStepButton, TextAreaWithLabel, VerticalSpace, Warning } from '../../components';
|
||||
import { ButtonArea, Dropdown, InputWithLabel, NextStepButton, TextAreaWithLabel, VerticalSpace, Warning } from '../../components';
|
||||
import useGenesisHashOptions from '../../hooks/useGenesisHashOptions';
|
||||
import useTranslation from '../../hooks/useTranslation';
|
||||
|
||||
interface AccountInfo {
|
||||
address: string;
|
||||
suri: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
className? : string;
|
||||
onNextStep: () => void;
|
||||
onAccountChange: (account: AccountInfo | null) => void;
|
||||
}
|
||||
|
||||
function ImportSeed ({ className, onAccountChange, onNextStep }: Props): React.ReactElement {
|
||||
function SeedAndPath ({ className, onAccountChange, onNextStep }: Props): React.ReactElement {
|
||||
const { t } = useTranslation();
|
||||
const genesisOptions = useGenesisHashOptions();
|
||||
const [address, setAddress] = useState('');
|
||||
const [seed, setSeed] = useState<string | null>(null);
|
||||
const [path, setPath] = useState<string | null>(null);
|
||||
const [advanced, setAdvances] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const [genesis, setGenesis] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// No need to validate an empty seed
|
||||
@ -43,9 +42,12 @@ function ImportSeed ({ className, onAccountChange, onNextStep }: Props): React.R
|
||||
|
||||
const suri = `${seed || ''}${path || ''}`;
|
||||
|
||||
validateSeed(suri).then((newAccount) => {
|
||||
validateSeed(suri).then((validatedAccount) => {
|
||||
setError('');
|
||||
setAddress(newAccount.address);
|
||||
setAddress(validatedAccount.address);
|
||||
// a spread operator here breaks tests, using Object.assign as a workaround
|
||||
const newAccount: AccountInfo = Object.assign(validatedAccount, { genesis });
|
||||
|
||||
onAccountChange(newAccount);
|
||||
}).catch(() => {
|
||||
setAddress('');
|
||||
@ -55,7 +57,7 @@ function ImportSeed ({ className, onAccountChange, onNextStep }: Props): React.R
|
||||
: t<string>('Invalid mnemonic seed')
|
||||
);
|
||||
});
|
||||
}, [t, seed, path, onAccountChange]);
|
||||
}, [t, seed, path, onAccountChange, genesis]);
|
||||
|
||||
const _onToggleAdvanced = useCallback(() => {
|
||||
setAdvances(!advanced);
|
||||
@ -82,6 +84,13 @@ function ImportSeed ({ className, onAccountChange, onNextStep }: Props): React.R
|
||||
{t<string>('Mnemonic needs to contain 12, 15, 18, 21, 24 words')}
|
||||
</Warning>
|
||||
)}
|
||||
<Dropdown
|
||||
className='genesisSelection'
|
||||
label={t<string>('Network')}
|
||||
onChange={setGenesis}
|
||||
options={genesisOptions}
|
||||
value={genesis}
|
||||
/>
|
||||
<div
|
||||
className='advancedToggle'
|
||||
onClick={_onToggleAdvanced}
|
||||
@ -119,24 +128,28 @@ function ImportSeed ({ className, onAccountChange, onNextStep }: Props): React.R
|
||||
);
|
||||
}
|
||||
|
||||
export default styled(ImportSeed)(({ theme }: ThemeProps) => `
|
||||
export default styled(SeedAndPath)(({ theme }: ThemeProps) => `
|
||||
.advancedToggle {
|
||||
color: ${theme.textColor};
|
||||
cursor: pointer;
|
||||
line-height: 14px;
|
||||
line-height: ${theme.lineHeight};
|
||||
letter-spacing: 0.04em;
|
||||
opacity: 0.65;
|
||||
text-transform: uppercase;
|
||||
|
||||
> span {
|
||||
font-size: 10px;
|
||||
font-size: ${theme.inputLabelFontSize};
|
||||
margin-left: .5rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.genesisSelection {
|
||||
margin-bottom: ${theme.fontSize};
|
||||
}
|
||||
|
||||
.seedInput {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: ${theme.fontSize};
|
||||
textarea {
|
||||
height: unset;
|
||||
}
|
||||
|
||||
@ -10,12 +10,18 @@ import { createAccountSuri } from '../../messaging';
|
||||
import { HeaderWithSteps } from '../../partials';
|
||||
import SeedAndPath from './SeedAndPath';
|
||||
|
||||
export interface AccountInfo {
|
||||
address: string;
|
||||
genesis?: string;
|
||||
suri: string;
|
||||
}
|
||||
|
||||
function ImportSeed (): React.ReactElement {
|
||||
const { t } = useTranslation();
|
||||
const { accounts } = useContext(AccountContext);
|
||||
const onAction = useContext(ActionContext);
|
||||
const [isBusy, setIsBusy] = useState(false);
|
||||
const [account, setAccount] = useState<null | { address: string; suri: string }>(null);
|
||||
const [account, setAccount] = useState<AccountInfo | null>(null);
|
||||
const [name, setName] = useState<string | null>(null);
|
||||
const [step1, setStep1] = useState(true);
|
||||
|
||||
@ -28,7 +34,7 @@ function ImportSeed (): React.ReactElement {
|
||||
if (name && password && account) {
|
||||
setIsBusy(true);
|
||||
|
||||
createAccountSuri(name, password, account.suri)
|
||||
createAccountSuri(name, password, account.suri, undefined, account.genesis)
|
||||
.then(() => onAction('/'))
|
||||
.catch((error): void => {
|
||||
setIsBusy(false);
|
||||
@ -49,6 +55,7 @@ function ImportSeed (): React.ReactElement {
|
||||
<div>
|
||||
<Address
|
||||
address={account?.address}
|
||||
genesisHash={account?.genesis}
|
||||
name={name}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -396,7 +396,7 @@ export default styled(Address)(({ theme }: ThemeProps) => `
|
||||
|
||||
.parentName {
|
||||
color: ${theme.labelColor};
|
||||
font-size: 10px;
|
||||
font-size: ${theme.inputLabelFontSize};
|
||||
line-height: 14px;
|
||||
overflow: hidden;
|
||||
padding: 0.25rem 0 0 0.8rem;
|
||||
|
||||
@ -25,7 +25,7 @@ export default styled(Label)(({ theme }: ThemeProps) => `
|
||||
color: ${theme.textColor};
|
||||
|
||||
label {
|
||||
font-size: 10px;
|
||||
font-size: ${theme.inputLabelFontSize};
|
||||
line-height: 14px;
|
||||
letter-spacing: 0.04em;
|
||||
opacity: 0.65;
|
||||
|
||||
@ -32,7 +32,7 @@ export default styled(MenuItem)(({ theme }: ThemeProps) => `
|
||||
> .itemTitle {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
font-size: 10px;
|
||||
font-size: ${theme.inputLabelFontSize};
|
||||
line-height: 14px;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
|
||||
@ -32,6 +32,7 @@ const darkTheme = {
|
||||
identiconBackground: '#F4F5F8',
|
||||
inputBackground: '#111218',
|
||||
inputBorderColor: '#43444B',
|
||||
inputLabelFontSize: '10px',
|
||||
labelColor: '#9F9E99',
|
||||
labelFontSize: '13px',
|
||||
labelLineHeight: '18px',
|
||||
|
||||
29
packages/extension-ui/src/hooks/useGenesisHashOptions.ts
Normal file
29
packages/extension-ui/src/hooks/useGenesisHashOptions.ts
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2019-2021 @polkadot/extension-ui authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { useRef } from 'react';
|
||||
|
||||
import chains from '../util/chains';
|
||||
import useTranslation from './useTranslation';
|
||||
|
||||
interface Option {
|
||||
text: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default function (): Option[] {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { current: hashes } = useRef([
|
||||
{
|
||||
text: t('Allow use on any chain'),
|
||||
value: ''
|
||||
},
|
||||
...chains.map(({ chain, genesisHash }) => ({
|
||||
text: chain,
|
||||
value: genesisHash
|
||||
}))
|
||||
]);
|
||||
|
||||
return hashes;
|
||||
}
|
||||
@ -9,9 +9,9 @@ import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
|
||||
import { PORT_EXTENSION } from '@polkadot/extension-base/defaults';
|
||||
import { metadataExpand } from '@polkadot/extension-chains';
|
||||
import allChains from '@polkadot/extension-chains/chains';
|
||||
import chrome from '@polkadot/extension-inject/chrome';
|
||||
|
||||
import allChains from './util/chains';
|
||||
import { getSavedMeta, setSavedMeta } from './MetadataCache';
|
||||
|
||||
interface Handler {
|
||||
@ -121,8 +121,8 @@ export async function createAccountHardware (address: string, hardwareType: stri
|
||||
return sendMessage('pri(accounts.create.hardware)', { accountIndex, address, addressOffset, genesisHash, hardwareType, name });
|
||||
}
|
||||
|
||||
export async function createAccountSuri (name: string, password: string, suri: string, type?: KeypairType): Promise<boolean> {
|
||||
return sendMessage('pri(accounts.create.suri)', { name, password, suri, type });
|
||||
export async function createAccountSuri (name: string, password: string, suri: string, type?: KeypairType, genesisHash?: string): Promise<boolean> {
|
||||
return sendMessage('pri(accounts.create.suri)', { genesisHash, name, password, suri, type });
|
||||
}
|
||||
|
||||
export async function createSeed (length?: SeedLengths, type?: KeypairType): Promise<{ address: string; seed: string }> {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2019-2021 @polkadot/extension-chains authors & contributors
|
||||
// Copyright 2019-2021 @polkadot/extension-ui authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { MetadataDefBase } from '@polkadot/extension-inject/types';
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright 2019-2021 @polkadot/extension-ui authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import chains from '@polkadot/extension-chains/chains';
|
||||
import chains from './chains';
|
||||
|
||||
export default function getNetworkMap (): Map<string, string> {
|
||||
const res = new Map<string, string>();
|
||||
|
||||
@ -152,5 +152,6 @@
|
||||
"Refresh": "",
|
||||
"Import Account": "",
|
||||
"Sign on Ledger": "",
|
||||
"Allow use on any chain": "",
|
||||
"Select network": ""
|
||||
}
|
||||
|
||||
@ -152,5 +152,6 @@
|
||||
"Refresh": "Rafraichir",
|
||||
"Import Account": "Importer",
|
||||
"Sign on Ledger": "Signer sur Ledger",
|
||||
"Allow use on any chain": "Toutes les blockchains",
|
||||
"Select network": "Sélectionner un réseau"
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user