handleClick()}
- data-testid={seedPhraseBoxTestId}
- onMouseOver={() => setShowTooltip(true)}
- onMouseLeave={() => setShowTooltip(false)}
- >
- {
- words.map((word, i) => (
+
+
handleClick()}
+ data-testid={seedPhraseBoxTestId}
+ onMouseOver={() => setShowTooltip(true)}
+ onMouseLeave={() => setShowTooltip(false)}
+ >
+ {words.map((word, i) => (
- ))
- }
- {
- showTooltip
- &&
- }
+ ))}
+ {showTooltip &&
}
+
+ {!revealed && (
+ <>
+
+
+
+ >
+ )}
);
@@ -66,9 +84,12 @@ export default SeedPhrase;
SeedPhrase.defaultProps = {
seedPhraseBoxTestId: 'seed-phrase-box',
+ className: '',
};
SeedPhrase.propTypes = {
+ onReveal: PropTypes.func.isRequired,
words: PropTypes.arrayOf(PropTypes.string).isRequired,
seedPhraseBoxTestId: PropTypes.string,
+ className: PropTypes.string,
};
diff --git a/source/components/SeedPhrase/styles.js b/source/components/SeedPhrase/styles.js
index 1b31d8b0..ed5d82d6 100644
--- a/source/components/SeedPhrase/styles.js
+++ b/source/components/SeedPhrase/styles.js
@@ -2,16 +2,21 @@ import { makeStyles } from '@material-ui/core/styles';
import SHADOW_1 from '@shared/styles/shadows';
import RAINBOW_GRADIENT from '@shared/styles/gradients';
+const RAINBOW_GRADIENT_BG = 'linear-gradient(96.51deg, rgba(255, 231, 1, 0.8) 8.72%, rgba(255, 0, 196, 0.8) 38.27%, rgba(0, 232, 255, 0.8) 68.28%, rgba(0, 255, 1, 0.8) 94.7%)';
+
export default makeStyles((theme) => ({
root: {
+ position: 'relative',
+ },
+ seedContainer: {
background: theme.palette.common.white,
boxShadow: SHADOW_1,
borderRadius: 10,
padding: 2,
- position: 'relative',
cursor: 'pointer',
+ maxWidth: 550,
width: '100%',
- height: '100%',
+ height: 185,
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
@@ -44,4 +49,31 @@ export default makeStyles((theme) => ({
tooltip: {
margin: '8px 0',
},
+ blurContainer: {
+ position: 'absolute',
+ height: '100%',
+ width: '100%',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ top: 0,
+ left: 0,
+ },
+ blur: {
+ height: '100%',
+ width: '100%',
+ margin: 12,
+ inset: 0,
+ zIndex: 2,
+ backdropFilter: 'blur(7px)',
+ borderRadius: 10,
+ },
+ rainbowBg: {
+ width: '100%',
+ height: '80%',
+ maxWidth: 350,
+ background: RAINBOW_GRADIENT_BG,
+ filter: 'blur(25px)',
+ borderRadius: 300,
+ },
}));
diff --git a/source/components/index.js b/source/components/index.js
index a4c768d8..99991437 100644
--- a/source/components/index.js
+++ b/source/components/index.js
@@ -8,12 +8,10 @@ export { default as Actions } from './Actions';
export { default as Tokens } from './Tokens';
export { default as Activity } from './Activity';
export { default as Apps } from './Apps';
-export { default as RevealSeedPhrase } from './RevealSeedPhrase';
export { default as SeedPhrase } from './SeedPhrase';
export { default as QRCode } from './QRCode';
export { default as SwapInfo } from './SwapInfo';
export { default as IDInput } from './IDInput';
-export { default as MadeBy } from './MadeBy';
export { default as ActionDialog } from './ActionDialog';
export { default as ContactItem } from './ContactItem';
export { default as ContactList } from './ContactList';
@@ -60,8 +58,6 @@ export { default as AssetFormat } from './AssetFormat';
export { default as USDFormat } from './USDFormat';
export { default as IncomingAction } from './IncomingAction';
export { default as DataDisplay } from './DataDisplay';
-export { default as FullscreenContainer } from './FullscreenContainer';
-export { default as ActionCard } from './ActionCard';
export { default as Alert } from './Alert';
export { default as CanisterInfoContainer } from './CanisterInfo/components/Container';
export { default as CanisterInfoItem } from './CanisterInfo/components/Item';
diff --git a/source/locales/en/translation.json b/source/locales/en/translation.json
index aa91353f..c17f2806 100644
--- a/source/locales/en/translation.json
+++ b/source/locales/en/translation.json
@@ -21,10 +21,6 @@
"copyTextAddress": "Copy address to clipboard",
"copiedText": "Copied!"
},
- "importPEM": {
- "added-account": "Account already added",
- "invalid-key": "Invalid PEM file"
- },
"profile": {
"myAccounts": "My Accounts",
"createAccount": "Create Account",
@@ -291,7 +287,8 @@
"seedMessage": "Keep this sh*t safe, forreal.",
"seedCheckbox": "I wrote down the Secret Recovery Phrase and put it somewhere safe.",
"passwordShortError": "The minimum is 8 characters, smh!",
- "passwordMatchError": "The passwords gotta match, smh!"
+ "passwordMatchError": "The passwords gotta match, smh!",
+ "pasteMnemonic": "You can paste the totality of your secret phrase into any input"
},
"contacts": {
"title": "Contacts",
@@ -408,7 +405,9 @@
"or": "or",
"browse": "browse",
"fileNotSupported": "File not supported. Try a different file.",
- "dropIt": "Drop it!"
+ "dropIt": "Drop it!",
+ "added-account": "Account already added",
+ "invalid-key": "Invalid PEM file"
},
"nfts": {
"allNfts": "All NFTs",
diff --git a/source/shared/utils/array.js b/source/shared/utils/array.js
index 2b573b07..f45e2ea2 100644
--- a/source/shared/utils/array.js
+++ b/source/shared/utils/array.js
@@ -1,2 +1,3 @@
// eslint-disable-next-line
export const areAllElementsIn = (elements, array) => elements.every((element) => array.includes(element));
+export const createArray = (length, fillValue) => new Array(length).fill(fillValue);
diff --git a/source/views/Extension/Views/ImportWallet/hooks/useSteps.jsx b/source/views/Extension/Views/ImportWallet/hooks/useSteps.jsx
index 8f7384d8..103699eb 100644
--- a/source/views/Extension/Views/ImportWallet/hooks/useSteps.jsx
+++ b/source/views/Extension/Views/ImportWallet/hooks/useSteps.jsx
@@ -1,12 +1,12 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect } from "react";
import { HANDLER_TYPES, sendMessage } from "@background/Keyring";
-import { toast } from 'react-toastify';
-import { LinkButton } from '@components';
-import { useTranslation } from 'react-i18next';
-import { useRouter } from '@components/Router';
-import BackIcon from '@assets/icons/back.svg';
-import Step1 from '../Steps/Step1';
-import Step2 from '../Steps/Step2';
+import { toast } from "react-toastify";
+import { LinkButton } from "@components";
+import { useTranslation } from "react-i18next";
+import { useRouter } from "@components/Router";
+import BackIcon from "@assets/icons/back.svg";
+import Step1 from "../Steps/Step1";
+import Step2 from "../Steps/Step2";
const useSteps = () => {
const [step, setStep] = useState(0);
@@ -18,10 +18,18 @@ const useSteps = () => {
const [importDisabled, setImportDisabled] = useState(true);
const handleChangeStep = (index) => setStep(index);
- const handleClose = () => navigator.navigate('home');
+ const handleClose = () => navigator.navigate("home");
- const leftButton = (onClick) =>
;
- const rightButton =
;
+ const leftButton = (onClick) => (
+
+ );
+ const rightButton = (
+
+ );
useEffect(() => {
if (userPemFile === null) {
@@ -31,22 +39,32 @@ const useSteps = () => {
setValidateLoading(true);
let fileReader = new FileReader();
- fileReader.readAsText(userPemFile);
+ try {
+ fileReader.readAsText(userPemFile);
+ } catch (e) {
+ toast(t("importPem.fileNotSupported"), { type: "error" });
+ setUserPemFile(null);
+
+ return;
+ }
fileReader.onloadend = async () => {
const content = fileReader.result;
- sendMessage({
- type: HANDLER_TYPES.VALIDATE_PEM,
- params: { pem: content },
- }, (response) => {
- const { isValid, errorType } = response;
- if (!isValid) {
- toast(t(`importPEM.${errorType}`), { type: 'error' });
- setUserPemFile(null);
+ sendMessage(
+ {
+ type: HANDLER_TYPES.VALIDATE_PEM,
+ params: { pem: content },
+ },
+ (response) => {
+ const { isValid, errorType } = response;
+ if (!isValid) {
+ toast(t(`importPem.${errorType}`), { type: "error" });
+ setUserPemFile(null);
+ }
+ setValidateLoading(false);
+ setImportDisabled(!isValid);
}
- setValidateLoading(false);
- setImportDisabled(!isValid);
- });
+ );
};
}, [userPemFile]);
@@ -66,10 +84,7 @@ const useSteps = () => {
center: `${t("importPem.importPEMfile")}`,
},
{
- component:
,
+ component:
,
right: rightButton,
center: `${t("importPem.walletDetails")}`,
},
diff --git a/source/views/Extension/Views/NFTDetails/index.jsx b/source/views/Extension/Views/NFTDetails/index.jsx
index 535f21d6..57830500 100644
--- a/source/views/Extension/Views/NFTDetails/index.jsx
+++ b/source/views/Extension/Views/NFTDetails/index.jsx
@@ -53,9 +53,9 @@ const NFTDetails = () => {
const name = `${nft?.name ?? `#${nft?.index}`}`;
const isICNS = collection?.name === 'ICNS';
- const openNFT = (url) => () => {
+ const openNFT = (url) => {
const parsedUrl = isICNS
- ? `https://icns.id/domains/${populatedNFT?.name.replace('.icp', '')}/detail`
+ ? `https://icns.id/domains/${nft?.name.replace('.icp', '')}/detail`
: url;
extension.tabs.create({
@@ -84,7 +84,7 @@ const NFTDetails = () => {
openNFT(nft?.url)}
data-testid="expand-nft"
/>
)}
@@ -129,7 +129,7 @@ const NFTDetails = () => {
{populatedNFT?.desc}
)}
- {populatedNFT?.metadata?.properties?.filter((prop) => typeof prop?.value !== 'object')?.length >= 1 && (
+ {!isICNS && populatedNFT?.metadata?.properties?.filter((prop) => typeof prop?.value !== 'object')?.length >= 1 && (
{
populatedNFT?.metadata?.properties?.map((prop) => ((
diff --git a/source/components/ActionCard/action-card.stories.jsx b/source/views/Options/Views/Welcome/components/ActionCard/action-card.stories.jsx
similarity index 100%
rename from source/components/ActionCard/action-card.stories.jsx
rename to source/views/Options/Views/Welcome/components/ActionCard/action-card.stories.jsx
diff --git a/source/components/ActionCard/index.jsx b/source/views/Options/Views/Welcome/components/ActionCard/index.jsx
similarity index 96%
rename from source/components/ActionCard/index.jsx
rename to source/views/Options/Views/Welcome/components/ActionCard/index.jsx
index bd94a24c..d55dd091 100644
--- a/source/components/ActionCard/index.jsx
+++ b/source/views/Options/Views/Welcome/components/ActionCard/index.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Typography } from '@material-ui/core';
-import Button from '../Button';
+import { Button } from '@components';
import useStyles from './styles';
const ActionCard = ({
diff --git a/source/components/ActionCard/styles.js b/source/views/Options/Views/Welcome/components/ActionCard/styles.js
similarity index 89%
rename from source/components/ActionCard/styles.js
rename to source/views/Options/Views/Welcome/components/ActionCard/styles.js
index 5bb7b7e9..62c644cf 100644
--- a/source/components/ActionCard/styles.js
+++ b/source/views/Options/Views/Welcome/components/ActionCard/styles.js
@@ -11,6 +11,8 @@ export default makeStyles((theme) => ({
width: '100%',
background: 'rgba(255, 255, 255, 0.4)',
borderRadius: 15,
+ maxWidth: 420,
+ margin: theme.spacing(1),
},
image: {
marginBottom: theme.spacing(1),
diff --git a/source/views/Options/Views/Welcome/components/Header/index.jsx b/source/views/Options/Views/Welcome/components/Header/index.jsx
deleted file mode 100644
index b03e098c..00000000
--- a/source/views/Options/Views/Welcome/components/Header/index.jsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Plug } from '@components';
-import { Typography } from '@material-ui/core';
-import useStyles from './styles';
-
-const Header = ({ title, subtitle, message }) => {
- const classes = useStyles();
-
- return (
-
-
-
{title}
-
{subtitle}
-
- );
-};
-
-export default Header;
-
-Header.propTypes = {
- title: PropTypes.string.isRequired,
- subtitle: PropTypes.string.isRequired,
- message: PropTypes.string.isRequired,
-};
diff --git a/source/views/Options/Views/Welcome/components/Header/styles.js b/source/views/Options/Views/Welcome/components/Header/styles.js
deleted file mode 100644
index 76bb6b2a..00000000
--- a/source/views/Options/Views/Welcome/components/Header/styles.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { makeStyles } from '@material-ui/core/styles';
-
-export default makeStyles((theme) => ({
- root: {
- height: 188,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'space-between',
- flexDirection: 'column',
- marginBottom: theme.spacing(1),
- },
- subtitle: {
- width: '102%',
- },
-}));
diff --git a/source/components/MadeBy/index.jsx b/source/views/Options/Views/Welcome/components/MadeByFleek/index.jsx
similarity index 87%
rename from source/components/MadeBy/index.jsx
rename to source/views/Options/Views/Welcome/components/MadeByFleek/index.jsx
index 4e33b19a..15276a0e 100644
--- a/source/components/MadeBy/index.jsx
+++ b/source/views/Options/Views/Welcome/components/MadeByFleek/index.jsx
@@ -3,7 +3,7 @@ import { fleekUrl } from '@shared/constants/urls';
import ThunderImg from '@assets/icons/options/thunder.svg';
import useStyles from './styles';
-const MadeBy = () => {
+const MadeByFleek = () => {
const classes = useStyles();
return (
@@ -13,4 +13,4 @@ const MadeBy = () => {
);
};
-export default MadeBy;
+export default MadeByFleek;
diff --git a/source/components/MadeBy/styles.js b/source/views/Options/Views/Welcome/components/MadeByFleek/styles.js
similarity index 85%
rename from source/components/MadeBy/styles.js
rename to source/views/Options/Views/Welcome/components/MadeByFleek/styles.js
index 20996100..1e0ba734 100644
--- a/source/components/MadeBy/styles.js
+++ b/source/views/Options/Views/Welcome/components/MadeByFleek/styles.js
@@ -8,6 +8,9 @@ export default makeStyles((theme) => ({
fontSize: 12,
fontWeight: 700,
alignItems: 'center',
+ position: 'absolute',
+ top: 30,
+ right: 30,
},
image: {
marginLeft: 3,
diff --git a/source/views/Options/Views/Welcome/components/MnemonicInput/index.jsx b/source/views/Options/Views/Welcome/components/MnemonicInput/index.jsx
new file mode 100644
index 00000000..cec7bdbb
--- /dev/null
+++ b/source/views/Options/Views/Welcome/components/MnemonicInput/index.jsx
@@ -0,0 +1,118 @@
+import React, { useCallback, useState } from 'react';
+import PropTypes from 'prop-types';
+import { useTranslation } from 'react-i18next';
+import { Typography } from '@material-ui/core';
+import Info from '@assets/icons/info.svg';
+
+import { TextInput } from '@components';
+import { createArray } from '@shared/utils/array';
+
+import useStyles from './styles';
+import ShowHideToggle from '../ShowHideToggle';
+import { clearClipboard, parseMnemonic } from './utils';
+
+const MNEMONIC_LENGTH = 12;
+
+const MnemonicInput = ({ onChange, draftMnemonic }) => {
+ const { t } = useTranslation();
+ const classes = useStyles();
+ const [pasteFailed, setPasteFailed] = useState(false);
+ const [showMnemonic, setShowMnemonic] = useState(createArray(MNEMONIC_LENGTH, false));
+
+ const toggleShowMnemonic = useCallback((index) => {
+ setShowMnemonic((currentShowMnemonic) => {
+ const newShowMnemonic = currentShowMnemonic.slice();
+ if (newShowMnemonic[index]) {
+ newShowMnemonic[index] = false;
+ } else {
+ newShowMnemonic.fill(false);
+ newShowMnemonic[index] = true;
+ }
+ return newShowMnemonic;
+ });
+ }, []);
+
+ const onMnemonicWordChange = useCallback(
+ (index, newWord) => {
+ setPasteFailed(false);
+ const newMnemonic = draftMnemonic.slice();
+ newMnemonic[index] = newWord.trim();
+ onChange(newMnemonic);
+ },
+ [draftMnemonic, onChange],
+ );
+
+ const onMnemonicPaste = useCallback(
+ (rawMnemonic) => {
+ const parsedMnemonic = parseMnemonic(rawMnemonic);
+ let newDraftMnemonic = parsedMnemonic.split(' ');
+ if (newDraftMnemonic.length > MNEMONIC_LENGTH) {
+ setPasteFailed(true);
+ return;
+ }
+ setPasteFailed(false);
+
+ // If paste content is shorter than 12 words, fill the rest with empty strings
+ if (newDraftMnemonic.length < MNEMONIC_LENGTH) {
+ newDraftMnemonic = newDraftMnemonic.concat(
+ createArray(MNEMONIC_LENGTH - newDraftMnemonic.length, ''),
+ );
+ }
+ setShowMnemonic(createArray(MNEMONIC_LENGTH, false));
+ onChange(newDraftMnemonic);
+ clearClipboard();
+ },
+ [onChange, pasteFailed, setPasteFailed],
+ );
+
+ return (
+
+
+
+ {t('welcome.pasteMnemonic')}
+
+
+ {[...Array(MNEMONIC_LENGTH).keys()].map((index) => {
+ const id = `mnemonic-word-${index}`;
+ return (
+
+ {`${index + 1}.`}
+ {
+ e.preventDefault();
+ onMnemonicWordChange(index, e.target.value);
+ }}
+ value={draftMnemonic[index]}
+ autoComplete="off"
+ onPaste={(event) => {
+ const newMnemonic = event.clipboardData.getData('text');
+ if (newMnemonic.trim().match(/\s/u)) {
+ event.preventDefault();
+ onMnemonicPaste(newMnemonic);
+ }
+ }}
+ />
+ toggleShowMnemonic(index)}
+ label={t('MnemonicToggleShow')}
+ />
+
+ );
+ })}
+
+
+ );
+};
+
+MnemonicInput.propTypes = {
+ onChange: PropTypes.func.isRequired,
+ draftMnemonic: PropTypes.arrayOf(PropTypes.string).isRequired,
+};
+
+export default MnemonicInput;
diff --git a/source/views/Options/Views/Welcome/components/MnemonicInput/styles.js b/source/views/Options/Views/Welcome/components/MnemonicInput/styles.js
new file mode 100644
index 00000000..e22d2ada
--- /dev/null
+++ b/source/views/Options/Views/Welcome/components/MnemonicInput/styles.js
@@ -0,0 +1,71 @@
+import { makeStyles } from '@material-ui/core/styles';
+
+export default makeStyles((theme) => ({
+ mnemonicContainer: {
+ width: '100%',
+ maxWidth: 702,
+ },
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ },
+ mnemonicWordsContainer: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '100%',
+ marginBottom: theme.spacing(2),
+ },
+ mnemonicWordInputContainer: {
+ width: '100%',
+ maxWidth: 200,
+ margin: 15,
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ },
+ mnemonicWordAction: {
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'flex-end',
+ alignItems: 'center',
+ gap: '8px',
+ },
+ mnemonicWordInput: {
+ height: 30,
+ maxWidth: 150,
+ },
+ divider: {
+ width: '100%',
+ height: 1,
+ backgroundColor: 'rgba(0, 0, 0, 0.16)',
+ marginBottom: theme.spacing(2),
+ },
+ footerContainer: {
+ padding: '0 45px',
+ },
+ passwordInputContainer: {
+ marginBottom: theme.spacing(2),
+ display: 'flex',
+ justifyContent: 'space-between',
+ width: '100%',
+ },
+ passwordInput: {
+ maxWidth: 290,
+ },
+ pasteMessage: {
+ display: 'flex',
+ alignItems: 'center',
+ color: '#767676',
+ opacity: 0.9,
+ marginBottom: 10,
+ },
+ infoIcon: {
+ marginRight: 5,
+ height: 16,
+ width: 16,
+ opacity: 0.5,
+ },
+}));
diff --git a/source/views/Options/Views/Welcome/components/MnemonicInput/utils.js b/source/views/Options/Views/Welcome/components/MnemonicInput/utils.js
new file mode 100644
index 00000000..596f8133
--- /dev/null
+++ b/source/views/Options/Views/Welcome/components/MnemonicInput/utils.js
@@ -0,0 +1,5 @@
+export function clearClipboard() {
+ window.navigator.clipboard.writeText('');
+}
+
+export const parseMnemonic = (mnemonic) => (mnemonic || '').trim().toLowerCase().match(/\w+/gu)?.join(' ') || '';
diff --git a/source/views/Options/Views/Welcome/components/ShowHideToggle/index.jsx b/source/views/Options/Views/Welcome/components/ShowHideToggle/index.jsx
new file mode 100644
index 00000000..cd8fb1d3
--- /dev/null
+++ b/source/views/Options/Views/Welcome/components/ShowHideToggle/index.jsx
@@ -0,0 +1,42 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { Eye, EyeOff } from 'react-feather';
+
+import useStyles from './styles';
+
+const ShowHideToggle = ({
+ show, label, name, onChange, disabled, size,
+}) => {
+ const classes = useStyles();
+ return (
+
+
+
+
+ );
+};
+
+ShowHideToggle.propTypes = {
+ show: PropTypes.bool.isRequired,
+ label: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func.isRequired,
+ disabled: PropTypes.bool.isRequired,
+ size: PropTypes.number,
+};
+
+ShowHideToggle.defaultProps = {
+ size: 17,
+};
+
+export default ShowHideToggle;
diff --git a/source/views/Options/Views/Welcome/components/ShowHideToggle/styles.js b/source/views/Options/Views/Welcome/components/ShowHideToggle/styles.js
new file mode 100644
index 00000000..c09cc3d5
--- /dev/null
+++ b/source/views/Options/Views/Welcome/components/ShowHideToggle/styles.js
@@ -0,0 +1,14 @@
+import { makeStyles } from "@material-ui/core/styles";
+
+export default makeStyles(() => ({
+ showHideToggleContainer: {
+ height: 17,
+ width: 17,
+ "& > label": {
+ cursor: "pointer",
+ },
+ },
+ showHideToggleInput: {
+ display: "none",
+ },
+}));
diff --git a/source/views/Options/Views/Welcome/hooks/useSteps.jsx b/source/views/Options/Views/Welcome/hooks/useSteps.jsx
index 9e6d0c95..4fe101e2 100644
--- a/source/views/Options/Views/Welcome/hooks/useSteps.jsx
+++ b/source/views/Options/Views/Welcome/hooks/useSteps.jsx
@@ -1,9 +1,9 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
ActionsStep,
CreatePasswordStep,
- ImportWalletStep,
+ ImportMnemonicStep,
MemeStep,
SeedPhraseStep,
} from '../steps';
@@ -24,8 +24,8 @@ const useSteps = () => {
setCurrentBranch(branch);
handleNextStep();
};
-
const handleSetMnemonic = (value) => setMnemonic(value);
+ useEffect(() => setMnemonic(null), [currentBranch]);
const branches = {
import: [
@@ -41,20 +41,11 @@ const useSteps = () => {
title: t('welcome.importWallet'),
subtitle: t('welcome.importSubtitle'),
message: t('welcome.importMessage'),
- component: ,
},
- {
- title: t('welcome.passwordTitle'),
- subtitle: t('welcome.passwordSubtitle'),
- message: t('welcome.passwordMessage'),
- component: ,
- },
{
title: t('welcome.memeTitle'),
subtitle: t('welcome.memeSubtitle'),
diff --git a/source/views/Options/Views/Welcome/index.jsx b/source/views/Options/Views/Welcome/index.jsx
index eef4f0f2..f3a74701 100644
--- a/source/views/Options/Views/Welcome/index.jsx
+++ b/source/views/Options/Views/Welcome/index.jsx
@@ -1,11 +1,13 @@
import React from 'react';
-import Grid from '@material-ui/core/Grid';
-import { FullscreenContainer, LinkButton } from '@components';
-import BackIcon from '@assets/icons/back.svg';
import { useTranslation } from 'react-i18next';
-import Header from './components/Header';
-import useSteps from './hooks/useSteps';
+import { Typography } from '@material-ui/core';
+
+import BackIcon from '@assets/icons/back.svg';
+import { LinkButton, Plug } from '@components';
+
import useStyles from './styles';
+import MadeByFleek from './components/MadeByFleek';
+import useSteps from './hooks/useSteps';
const Welcome = () => {
const { t } = useTranslation();
@@ -17,26 +19,24 @@ const Welcome = () => {
} = useSteps();
const step = steps[currentStep];
-
+ const isMiddleStep = currentStep > 0 && currentStep < steps.length - 1;
return (
-
-
- {
- (currentStep > 0 && currentStep < steps.length - 1)
- && (
+
+
+
+ {isMiddleStep && (
- )
- }
-
-
-
- {
- step.component
- }
-
-
+ )}
+
+
{step.title}
+
{step.subtitle}
+
+
+ {step.component}
+
+
);
};
diff --git a/source/views/Options/Views/Welcome/steps/ActionsStep.jsx b/source/views/Options/Views/Welcome/steps/ActionsStep.jsx
deleted file mode 100644
index 855f0aec..00000000
--- a/source/views/Options/Views/Welcome/steps/ActionsStep.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { ActionCard } from '@components';
-import Grid from '@material-ui/core/Grid';
-import ImportImg from '@assets/icons/options/importwallet.svg';
-import CreateImg from '@assets/icons/options/createwallet.svg';
-import { useTranslation } from 'react-i18next';
-
-const ActionsStep = ({ handleChangeBranch }) => {
- const { t } = useTranslation();
-
- return (
- <>
-
- handleChangeBranch('import')}
- buttonProps={{ 'data-testid': 'import-wallet-button' }}
- />
-
-
-
- handleChangeBranch('create')}
- buttonProps={{ 'data-testid': 'create-wallet-button' }}
- />
-
- >
- );
-};
-
-export default ActionsStep;
-
-ActionsStep.propTypes = {
- handleChangeBranch: PropTypes.func.isRequired,
-};
diff --git a/source/views/Options/Views/Welcome/steps/ActionsStep/index.jsx b/source/views/Options/Views/Welcome/steps/ActionsStep/index.jsx
new file mode 100644
index 00000000..1ab0ef7d
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/ActionsStep/index.jsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { useTranslation } from 'react-i18next';
+
+import ImportImg from '@assets/icons/options/importwallet.svg';
+import CreateImg from '@assets/icons/options/createwallet.svg';
+
+import ActionCard from '../../components/ActionCard';
+import useStyles from './styles';
+
+const ActionsStep = ({ handleChangeBranch }) => {
+ const { t } = useTranslation();
+ const classes = useStyles();
+ return (
+
+
handleChangeBranch('import')}
+ buttonProps={{ 'data-testid': 'import-wallet-button' }}
+ />
+ handleChangeBranch('create')}
+ buttonProps={{ 'data-testid': 'create-wallet-button' }}
+ />
+
+ );
+};
+
+export default ActionsStep;
+
+ActionsStep.propTypes = {
+ handleChangeBranch: PropTypes.func.isRequired,
+};
diff --git a/source/views/Options/Views/Welcome/steps/ActionsStep/styles.js b/source/views/Options/Views/Welcome/steps/ActionsStep/styles.js
new file mode 100644
index 00000000..95ec9f0f
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/ActionsStep/styles.js
@@ -0,0 +1,11 @@
+import { makeStyles } from '@material-ui/core/styles';
+
+export default makeStyles(() => ({
+ actionsStepContainer: {
+ display: 'flex',
+ justifyContent: 'center',
+ maxWidth: 900,
+ width: '100%',
+ flexWrap: 'wrap',
+ },
+}));
diff --git a/source/views/Options/Views/Welcome/steps/CreatePasswordStep.jsx b/source/views/Options/Views/Welcome/steps/CreatePasswordStep/index.jsx
similarity index 61%
rename from source/views/Options/Views/Welcome/steps/CreatePasswordStep.jsx
rename to source/views/Options/Views/Welcome/steps/CreatePasswordStep/index.jsx
index 47dcf955..52b398a5 100644
--- a/source/views/Options/Views/Welcome/steps/CreatePasswordStep.jsx
+++ b/source/views/Options/Views/Welcome/steps/CreatePasswordStep/index.jsx
@@ -1,6 +1,5 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
-import Grid from '@material-ui/core/Grid';
import { useTranslation } from 'react-i18next';
import {
Alert, Button, FormItem, TextInput,
@@ -9,7 +8,7 @@ import { HANDLER_TYPES, sendMessage } from '@background/Keyring';
import facepalmEmoji from '@assets/icons/facepalm.svg';
import { getRandomEmoji } from '@shared/constants/emojis';
import { clearStorage } from '@modules/storageManager';
-import useStyles from '../styles';
+import useStyles from './styles';
const CreatePasswordStep = ({ handleNextStep, handleSetMnemonic, mnemonic }) => {
const { t } = useTranslation();
@@ -61,55 +60,51 @@ const CreatePasswordStep = ({ handleNextStep, handleSetMnemonic, mnemonic }) =>
const handleKeyPress = (e) => e.key === 'Enter' && handleCreateAccount();
return (
- <>
-
-
+
+
)}
- />
-
-
-
+ />
+
)}
- />
-
-
-
-
-
-
-
+ />
+
+
{passwordError && (
-
+
{t(`${passwordError}`)}
-
+
)}
- >
+
);
};
diff --git a/source/views/Options/Views/Welcome/steps/CreatePasswordStep/styles.js b/source/views/Options/Views/Welcome/steps/CreatePasswordStep/styles.js
new file mode 100644
index 00000000..61fb6c41
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/CreatePasswordStep/styles.js
@@ -0,0 +1,27 @@
+import { makeStyles } from '@material-ui/core/styles';
+
+export default makeStyles((theme) => ({
+ createPasswordContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ textAlign: 'center',
+ width: '100%',
+ height: '100%',
+ maxWidth: 600,
+ },
+ marginBottom: {
+ marginBottom: theme.spacing(2),
+ },
+ passwordError: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+
+ '& > img': {
+ marginRight: '1rem',
+ },
+ },
+}));
diff --git a/source/views/Options/Views/Welcome/steps/ImportMnemonicStep/index.jsx b/source/views/Options/Views/Welcome/steps/ImportMnemonicStep/index.jsx
new file mode 100644
index 00000000..e8a2a4b8
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/ImportMnemonicStep/index.jsx
@@ -0,0 +1,161 @@
+import React, { useCallback, useEffect, useState } from 'react';
+import PropTypes from 'prop-types';
+import { useTranslation } from 'react-i18next';
+import * as bip39 from 'bip39';
+
+import { HANDLER_TYPES, sendMessage } from '@background/Keyring';
+import { clearStorage } from '@modules/storageManager';
+import { getRandomEmoji } from '@shared/constants/emojis';
+import { createArray } from '@shared/utils/array';
+import { Alert, Button, FormInput } from '@components';
+import facepalmEmoji from '@assets/icons/facepalm.svg';
+
+import useStyles from './styles';
+import MnemonicInput from '../../components/MnemonicInput';
+
+const MNEMONIC_LENGTH = 12;
+
+export function clearClipboard() {
+ window.navigator.clipboard.writeText('');
+}
+
+const isValidMnemonic = (mnemonic) => bip39.validateMnemonic(mnemonic);
+
+const ImportWalletStep = ({ handleNextStep, handleSetMnemonic }) => {
+ const { t } = useTranslation();
+ const classes = useStyles();
+ const [draftMnemonic, setDraftMnemonic] = useState(
+ createArray(MNEMONIC_LENGTH, ''),
+ );
+ const [confirmPassword, setConfirmPassword] = useState('');
+ const [confirmPasswordError, setConfirmPasswordError] = useState('');
+ const [password, setPassword] = useState('');
+ const [passwordError, setPasswordError] = useState('');
+
+ const [invalidMnemonic, setInvalidMnemonic] = useState(true);
+
+ const onMnemonicChange = (newDraftMnemonic) => {
+ let newMnemonicError = '';
+ const joinedDraftMnemonic = newDraftMnemonic.join(' ').trim().toLowerCase();
+ if (newDraftMnemonic.some((word) => word !== '')) {
+ if (newDraftMnemonic.some((word) => word === '')) {
+ newMnemonicError = t('seedPhraseReq');
+ } else if (!isValidMnemonic(joinedDraftMnemonic)) {
+ setInvalidMnemonic(true);
+ newMnemonicError = t('invalidSeedPhrase');
+ }
+ }
+ setInvalidMnemonic(newMnemonicError?.length);
+ setDraftMnemonic(newDraftMnemonic);
+ handleSetMnemonic(newMnemonicError ? '' : newDraftMnemonic);
+ };
+
+ const handleCreateAccount = async () => {
+ // clean the storage before initiating keyring
+ clearStorage();
+ const params = {
+ password,
+ mnemonic: draftMnemonic.join(' '),
+ icon: getRandomEmoji(),
+ };
+ sendMessage({ type: HANDLER_TYPES.IMPORT, params }, (response) => {
+ handleSetMnemonic(response?.mnemonic);
+ });
+ handleNextStep();
+ };
+
+ const onPasswordChange = useCallback(
+ (event) => {
+ const newPassword = event.target.value;
+ let newConfirmPasswordError = '';
+ let newPasswordError = '';
+
+ if (newPassword && newPassword.length < 8) {
+ newPasswordError = t('welcome.passwordShortError');
+ }
+
+ if (confirmPassword && newPassword !== confirmPassword) {
+ newConfirmPasswordError = t('welcome.passwordMatchError');
+ }
+
+ setPassword(newPassword);
+ setPasswordError(newPasswordError);
+ setConfirmPasswordError(newConfirmPasswordError);
+ },
+ [confirmPassword, t],
+ );
+
+ const onConfirmPasswordChange = useCallback(
+ (event) => {
+ const newConfirmPassword = event.target.value;
+ let newConfirmPasswordError = '';
+
+ if (password !== newConfirmPassword) {
+ newConfirmPasswordError = t('welcome.passwordMatchError');
+ }
+
+ setConfirmPassword(newConfirmPassword);
+ setConfirmPasswordError(newConfirmPasswordError);
+ },
+ [password, t],
+ );
+ const isDisabled = invalidMnemonic
+ || !password
+ || !confirmPassword
+ || passwordError
+ || confirmPasswordError;
+
+ useEffect(() => setDraftMnemonic(createArray(MNEMONIC_LENGTH, '')), []);
+ return (
+
+
+
+
+
+
+
+
+
+
+ {(passwordError || confirmPasswordError) && (
+
+
+
{passwordError || confirmPasswordError}
+
+ )}
+
+
+ );
+};
+
+export default ImportWalletStep;
+
+ImportWalletStep.propTypes = {
+ handleNextStep: PropTypes.func.isRequired,
+ handleSetMnemonic: PropTypes.func.isRequired,
+};
diff --git a/source/views/Options/Views/Welcome/steps/ImportMnemonicStep/styles.js b/source/views/Options/Views/Welcome/steps/ImportMnemonicStep/styles.js
new file mode 100644
index 00000000..0ab79f57
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/ImportMnemonicStep/styles.js
@@ -0,0 +1,69 @@
+import { makeStyles } from '@material-ui/core/styles';
+
+export default makeStyles((theme) => ({
+ mnemonicContainer: {
+ width: '100%',
+ maxWidth: 702,
+ },
+ mnemonicWordsContainer: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '100%',
+ marginBottom: theme.spacing(2),
+ },
+ mnemonicWordInputContainer: {
+ width: '100%',
+ maxWidth: 200,
+ margin: 15,
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ },
+ mnemonicWordAction: {
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'flex-end',
+ alignItems: 'center',
+ gap: '8px',
+ },
+ mnemonicWordInput: {
+ height: 30,
+ maxWidth: 150,
+ },
+ divider: {
+ width: '100%',
+ height: 1,
+ backgroundColor: 'rgba(0, 0, 0, 0.16)',
+ marginBottom: theme.spacing(2),
+ },
+ footerContainer: {
+ padding: '0 45px',
+ },
+ passwordInputContainer: {
+ marginBottom: theme.spacing(2),
+ display: 'flex',
+ justifyContent: 'space-between',
+ width: '100%',
+ },
+ passwordInput: {
+ maxWidth: 290,
+ },
+ submitButton: {
+ marginBottom: 20,
+ },
+ pwdAlert: {
+ margin: '20px 0',
+ },
+ passwordError: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+
+ '& > img': {
+ marginRight: '1rem',
+ },
+ },
+}));
diff --git a/source/views/Options/Views/Welcome/steps/ImportWalletStep.jsx b/source/views/Options/Views/Welcome/steps/ImportWalletStep.jsx
deleted file mode 100644
index ab1262f9..00000000
--- a/source/views/Options/Views/Welcome/steps/ImportWalletStep.jsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import Grid from '@material-ui/core/Grid';
-import { useTranslation } from 'react-i18next';
-import { Button, FormItem, TextInput } from '@components';
-import * as bip39 from 'bip39';
-
-const ImportWalletStep = ({ handleNextStep, handleSetMnemonic }) => {
- const { t } = useTranslation();
-
- const [text, setText] = useState('');
- const [invalidMnemonic, setInvalidMnemonic] = useState(false);
-
- const handleChangeText = (e) => {
- setText(e.target.value);
- setInvalidMnemonic(false);
- };
-
- const handleImportMnemonic = () => {
- const trimmedText = text.trim();
-
- const isValid = bip39.validateMnemonic(trimmedText);
- if (isValid) {
- handleSetMnemonic(trimmedText);
- handleNextStep();
- } else {
- setInvalidMnemonic(true);
- }
- };
-
- const handleValidateMnemonic = () => (
- text === ''
- || text.trim().split(/\s+/g).length !== 12
- || invalidMnemonic
- );
-
- return (
- <>
-
-
- )}
- />
-
-
-
-
- >
- );
-};
-
-export default ImportWalletStep;
-
-ImportWalletStep.propTypes = {
- handleNextStep: PropTypes.func.isRequired,
- handleSetMnemonic: PropTypes.func.isRequired,
-};
diff --git a/source/views/Options/Views/Welcome/steps/SeedPhraseStep.jsx b/source/views/Options/Views/Welcome/steps/SeedPhraseStep.jsx
deleted file mode 100644
index 560607a0..00000000
--- a/source/views/Options/Views/Welcome/steps/SeedPhraseStep.jsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import Grid from '@material-ui/core/Grid';
-import { useTranslation } from 'react-i18next';
-import {
- Button, Checkbox, SeedPhrase, RevealSeedPhrase,
-} from '@components';
-import useStyles from '../styles';
-
-const SeedPhraseStep = ({ handleNextStep, mnemonic }) => {
- const { t } = useTranslation();
- const [checked, setChecked] = useState(false);
- const [reveal, setReveal] = useState(false);
- const classes = useStyles();
-
- const handleChangeCheckbox = (event) => { setChecked(event.target.checked); };
-
- if (mnemonic) {
- return (
- <>
-
- {
- !reveal
- && (
- <>
- setReveal(true)}
- style={{
- position: 'absolute',
- zIndex: 3,
- margin: 'auto',
- inset: 0,
- }}
- />
-
- >
- )
- }
-
-
-
-
-
-
-
-
- >
- );
- }
-
- return null;
-};
-
-export default SeedPhraseStep;
-
-SeedPhraseStep.defaultProps = {
- mnemonic: null,
-};
-
-SeedPhraseStep.propTypes = {
- handleNextStep: PropTypes.func.isRequired,
- mnemonic: PropTypes.arrayOf(PropTypes.string),
-};
diff --git a/source/views/Options/Views/Welcome/steps/SeedPhraseStep/index.jsx b/source/views/Options/Views/Welcome/steps/SeedPhraseStep/index.jsx
new file mode 100644
index 00000000..011bc5da
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/SeedPhraseStep/index.jsx
@@ -0,0 +1,55 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+import { useTranslation } from 'react-i18next';
+import {
+ Button, Checkbox, SeedPhrase,
+} from '@components';
+import useStyles from './styles';
+
+const SeedPhraseStep = ({ handleNextStep, mnemonic }) => {
+ const { t } = useTranslation();
+ const [checked, setChecked] = useState(false);
+ const [reveal, setReveal] = useState(false);
+ const classes = useStyles();
+
+ const handleChangeCheckbox = (event) => { setChecked(event.target.checked); };
+
+ if (mnemonic) {
+ return (
+
+
+ setReveal(true)} />
+
+
+
+
+ );
+ }
+
+ return null;
+};
+
+export default SeedPhraseStep;
+
+SeedPhraseStep.defaultProps = {
+ mnemonic: null,
+};
+
+SeedPhraseStep.propTypes = {
+ handleNextStep: PropTypes.func.isRequired,
+ mnemonic: PropTypes.arrayOf(PropTypes.string),
+};
diff --git a/source/views/Options/Views/Welcome/steps/SeedPhraseStep/styles.js b/source/views/Options/Views/Welcome/steps/SeedPhraseStep/styles.js
new file mode 100644
index 00000000..4abeb0b4
--- /dev/null
+++ b/source/views/Options/Views/Welcome/steps/SeedPhraseStep/styles.js
@@ -0,0 +1,20 @@
+import { makeStyles } from '@material-ui/core/styles';
+
+export default makeStyles((theme) => ({
+ seedphraseStepContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ width: '100%',
+ maxWidth: 545,
+ },
+ seedPhraseContainer: {
+ height: 185,
+ position: 'relative',
+ marginBottom: theme.spacing(2),
+ },
+ checkbox: {
+ marginBottom: theme.spacing(2),
+ paddingLeft: 5,
+ },
+}));
diff --git a/source/views/Options/Views/Welcome/steps/index.jsx b/source/views/Options/Views/Welcome/steps/index.jsx
index e071e1f1..8ed89ac0 100644
--- a/source/views/Options/Views/Welcome/steps/index.jsx
+++ b/source/views/Options/Views/Welcome/steps/index.jsx
@@ -1,5 +1,5 @@
export { default as ActionsStep } from './ActionsStep';
export { default as CreatePasswordStep } from './CreatePasswordStep';
-export { default as ImportWalletStep } from './ImportWalletStep';
+export { default as ImportMnemonicStep } from './ImportMnemonicStep';
export { default as MemeStep } from './MemeStep';
export { default as SeedPhraseStep } from './SeedPhraseStep';
diff --git a/source/views/Options/Views/Welcome/styles.js b/source/views/Options/Views/Welcome/styles.js
index 69121760..a2785a8e 100644
--- a/source/views/Options/Views/Welcome/styles.js
+++ b/source/views/Options/Views/Welcome/styles.js
@@ -1,40 +1,43 @@
import { makeStyles } from '@material-ui/core/styles';
export default makeStyles((theme) => ({
- goBack: {
- position: 'absolute',
- left: 0,
- top: 0,
- },
- blur: {
- height: 'calc(100% - 24px)',
- width: 'calc(100% - 24px)',
- position: 'absolute',
- margin: 12,
- inset: 0,
- zIndex: 2,
- backdropFilter: 'blur(7px)',
- borderRadius: 10,
-
- '@supports ( -moz-appearance:none )': {
- background: 'white',
- },
+ welcomeContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ textAlign: 'center',
+ width: '100%',
+ height: '100%',
+ minHeight: '100vh',
+ padding: `${theme.spacing(4)}px 0`,
+ position: 'relative',
+ background:
+ 'linear-gradient(122.45deg, rgba(255, 231, 1, 0.2) 15.68%, rgba(250, 81, 211, 0.2) 39.58%, rgba(16, 217, 237, 0.2) 63.84%, rgba(82, 255, 83, 0.2) 85.21%)',
},
- marginBottom: {
+ headerContainer: {
+ height: 190,
+ maxWidth: 540,
+ width: '100%',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ flexDirection: 'column',
marginBottom: theme.spacing(2),
},
- passwordError: {
+ stepContainer: {
+ width: '100%',
+ maxWidth: 950,
+ padding: theme.spacing(1),
display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
justifyContent: 'center',
-
- '& > img': {
- marginRight: '1rem',
- },
+ },
+ goBack: {
+ alignSelf: 'flex-start',
},
memeContainer: {
width: '100%',
+ maxWidth: 400,
background: 'white',
borderRadius: 5,
display: 'flex',
diff --git a/tests/e2e/edit-account.test.js b/tests/e2e/edit-account.test.js
index 99622f8c..e34fb555 100644
--- a/tests/e2e/edit-account.test.js
+++ b/tests/e2e/edit-account.test.js
@@ -89,7 +89,7 @@ const learnMoreButtonClick = async (browser, page) => {
const newPage = await newPagePromise;
const url = await newPage.evaluate(() => document.location.href);
- expect(url).toBe('https://medium.com/@plug_wallet/669b192a2ace');
+ expect(url).toContain('https://medium.com/plugwallet/internet-computer-ids-101-669b192a2ace');
};
const waitForWalletName = async (page, walletName, timeout = 1000) => {
diff --git a/tests/e2e/import-create-account.test.js b/tests/e2e/import-create-account.test.js
index d6e34811..82a23049 100644
--- a/tests/e2e/import-create-account.test.js
+++ b/tests/e2e/import-create-account.test.js
@@ -1,3 +1,5 @@
+const { fillSeedPhraseInput } = require('../utils/seed');
+
const MINIMUM_PLUG_VERSION_ALLOWED = 60;
const getErrorMessage = async (page, error) => {
@@ -36,10 +38,7 @@ describe('Import/Create', () => {
});
test('failing on incorrect seedphrase', async () => {
- const seedphraseTextarea = await page.getByTestId('seedphrase-input');
- await seedphraseTextarea.click();
- await seedphraseTextarea.type(badSeedphrase);
-
+ await fillSeedPhraseInput(page, badSeedphrase);
const submitImportButton = await page.getByTestId('confirm-seedphrase-button');
await submitImportButton.click();
@@ -52,14 +51,12 @@ describe('Import/Create', () => {
});
test('failing on missmatched passwords', async () => {
- const seedphraseTextarea = await page.getByTestId('seedphrase-input');
- await seedphraseTextarea.click();
- await seedphraseTextarea.type(secrets.seedphrase);
+ await fillSeedPhraseInput(page, secrets.seedphrase);
const submitImportButton = await page.getByTestId('confirm-seedphrase-button');
await submitImportButton.click();
- const newPasswordInput = await page.getByTestId('new-password-input');
+ const newPasswordInput = await page.getByTestId('enter-password-input');
const confirmPasswordInput = await page.getByTestId('confirm-password-input');
await newPasswordInput.click();
@@ -67,21 +64,19 @@ describe('Import/Create', () => {
await confirmPasswordInput.click();
await confirmPasswordInput.type('MissMatchedPassword');
- const submitPasswordButton = await page.getByTestId('password-confirmation-button');
+ const submitPasswordButton = await page.getByTestId('confirm-seedphrase-button');
await submitPasswordButton.click();
await getErrorMessage(page, 'The passwords gotta match, smh!');
});
test('failing on password shorter than 12 characters', async () => {
- const seedphraseTextarea = await page.getByTestId('seedphrase-input');
- await seedphraseTextarea.click();
- await seedphraseTextarea.type(secrets.seedphrase);
+ await fillSeedPhraseInput(page, secrets.seedphrase);
const submitImportButton = await page.getByTestId('confirm-seedphrase-button');
await submitImportButton.click();
- const newPasswordInput = await page.getByTestId('new-password-input');
+ const newPasswordInput = await page.getByTestId('enter-password-input');
const confirmPasswordInput = await page.getByTestId('confirm-password-input');
await newPasswordInput.click();
@@ -89,21 +84,19 @@ describe('Import/Create', () => {
await confirmPasswordInput.click();
await confirmPasswordInput.type('123');
- const submitPasswordButton = await page.getByTestId('password-confirmation-button');
+ const submitPasswordButton = await page.getByTestId('confirm-seedphrase-button');
await submitPasswordButton.click();
await getErrorMessage(page, 'The minimum is 8 characters, smh!');
});
test('importing wallet correctly', async () => {
- const seedphraseTextarea = await page.getByTestId('seedphrase-input');
- await seedphraseTextarea.click();
- await seedphraseTextarea.type(secrets.seedphrase);
+ await fillSeedPhraseInput(page, secrets.seedphrase);
const submitImportButton = await page.getByTestId('confirm-seedphrase-button');
await submitImportButton.click();
- const newPasswordInput = await page.getByTestId('new-password-input');
+ const newPasswordInput = await page.getByTestId('enter-password-input');
const confirmPasswordInput = await page.getByTestId('confirm-password-input');
await newPasswordInput.click();
@@ -111,7 +104,7 @@ describe('Import/Create', () => {
await confirmPasswordInput.click();
await confirmPasswordInput.type(secrets.password);
- const submitPasswordButton = await page.getByTestId('password-confirmation-button');
+ const submitPasswordButton = await page.getByTestId('confirm-seedphrase-button');
await submitPasswordButton.click();
await page.goto(chromeData.popupUrl);
@@ -139,7 +132,7 @@ describe('Import/Create', () => {
});
test('fails on missmatched passwords', async () => {
- const newPasswordInput = await page.getByTestId('new-password-input');
+ const newPasswordInput = await page.getByTestId('enter-password-input');
await newPasswordInput.click();
await newPasswordInput.type('TestPassword123');
@@ -154,7 +147,7 @@ describe('Import/Create', () => {
});
test('fails on password shorter than 12 characters', async () => {
- const newPasswordInput = await page.getByTestId('new-password-input');
+ const newPasswordInput = await page.getByTestId('enter-password-input');
await newPasswordInput.click();
await newPasswordInput.type('123');
@@ -169,7 +162,7 @@ describe('Import/Create', () => {
});
test('correctly creates', async () => {
- const newPasswordInput = await page.getByTestId('new-password-input');
+ const newPasswordInput = await page.getByTestId('enter-password-input');
await newPasswordInput.click();
await newPasswordInput.type(secrets.password);
diff --git a/tests/setup/jestSetup.js b/tests/setup/jestSetup.js
index ece314b5..1c65b90a 100644
--- a/tests/setup/jestSetup.js
+++ b/tests/setup/jestSetup.js
@@ -1,3 +1,5 @@
+const { fillSeedPhraseInput } = require('../utils/seed');
+
require('dotenv').config();
const PAGE_TITLE = 'Plug';
@@ -122,23 +124,18 @@ const importAccount = async (page, seedphrase, password) => {
const importButton = await getByTestId(page, 'import-wallet-button');
await importButton.click();
- const seedphraseTextArea = await getByTestId(page, 'seedphrase-input');
- await seedphraseTextArea.click();
- await seedphraseTextArea.type(seedphrase);
-
- const confirmSeedphraseButton = await getByTestId(page, 'confirm-seedphrase-button');
- await confirmSeedphraseButton.click();
+ await fillSeedPhraseInput(page, seedphrase);
- const newPasswordInput = await getByTestId(page, 'new-password-input');
- const confirmPasswordInput = await getByTestId(page, 'confirm-password-input');
+ const newPasswordInput = await getByTestId(page, 'enter-password-input');
+ const confirmPasswordInput = await getByTestId(page, 'confirm-password-input', true);
await newPasswordInput.click();
await newPasswordInput.type(password);
await confirmPasswordInput.click();
await confirmPasswordInput.type(password);
- const submitPasswordButton = await getByTestId(page, 'password-confirmation-button');
- await submitPasswordButton.click();
+ const confirmSeedphraseButton = await getByTestId(page, 'confirm-seedphrase-button');
+ await confirmSeedphraseButton.click();
};
const unlock = async (page, password) => {
diff --git a/tests/utils/seed.js b/tests/utils/seed.js
new file mode 100644
index 00000000..450cbbf3
--- /dev/null
+++ b/tests/utils/seed.js
@@ -0,0 +1,12 @@
+const fillSeedPhraseInput = async (page, seedPhrase) => {
+ const seedArray = seedPhrase.trim().split(' ');
+ for (let i = 0; i < seedArray.length; i += 1) {
+ const seedPhraseInput = await page.getByTestId(`seedphrase-input-${i + 1}`);
+ await seedPhraseInput.click();
+ await seedPhraseInput.type(seedArray[i]);
+ }
+};
+
+module.exports = {
+ fillSeedPhraseInput,
+};