Skip to content

Commit

Permalink
Merge pull request #648 from Psychedelic/feat/import-identity-string
Browse files Browse the repository at this point in the history
Feat/import identity string
  • Loading branch information
Cancuuu authored Nov 4, 2022
2 parents 75f56ec + a76e72d commit 7f3ff23
Show file tree
Hide file tree
Showing 16 changed files with 449 additions and 12 deletions.
3 changes: 3 additions & 0 deletions source/Background/Keyring/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const HANDLER_TYPES = {
GET_CURRENT_NETWORK: 'get-current-network',
IMPORT_PEM_ACCOUNT: 'import-pem-account',
REMOVE_PEM_ACCOUNT: 'remove-pem-account',
VALIDATE_PEM: 'validate-pem',
REMOVE_CUSTOM_TOKEN: 'remove-custom-token',
};

Expand Down Expand Up @@ -146,6 +147,7 @@ export const getKeyringErrorMessage = (type) => ({
[HANDLER_TYPES.REMOVE_CUSTOM_TOKEN]: 'removing custom token',
[HANDLER_TYPES.IMPORT_PEM_ACCOUNT]: 'importing account from pem',
[HANDLER_TYPES.REMOVE_PEM_ACCOUNT]: 'removing pem account',
[HANDLER_TYPES.VALIDATE_PEM]: 'validate pem',
}[type]);

export const sendMessage = (args, callback) => {
Expand Down Expand Up @@ -199,6 +201,7 @@ export const getKeyringHandler = (type, keyring) => ({
[HANDLER_TYPES.IMPORT_PEM_ACCOUNT]: async (params) => keyring.importAccountFromPem(params),
[HANDLER_TYPES.CREATE_PRINCIPAL]: async (params) => keyring.createPrincipal(params),
[HANDLER_TYPES.REMOVE_PEM_ACCOUNT]: async (params) => keyring.deleteImportedAccount(params),
[HANDLER_TYPES.VALIDATE_PEM]: async (params) => keyring.validatePem(params),
[HANDLER_TYPES.SET_CURRENT_PRINCIPAL]:
async (walletId) => {
await keyring.setCurrentPrincipal(walletId);
Expand Down
9 changes: 9 additions & 0 deletions source/assets/new-key.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions source/assets/paper.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions source/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,12 @@
"dfxUse": "dfx identity use <identity name>",
"selectAccount": "Select Account"
},
"importWallet": {
"importWallet": "Import Wallet"
},
"importPem": {
"importPEMfile": "Import PEM file",
"description": "Import wallet through a PEM file",
"editWalletPic": "Edit Wallet Pic",
"walletDetails": "Wallet Details",
"dragAndDrop": "Drag and Drop",
Expand All @@ -406,6 +410,12 @@
"fileNotSupported": "File not supported. Try a different file.",
"dropIt": "Drop it!"
},
"importPrivateKey": {
"importPrivateKey": "Import Private Key",
"description": "Import wallet through a Private Key",
"privateKey": "Private Key",
"invalidString": "Invalid String. Please, try again."
},
"nfts": {
"allNfts": "All NFTs",
"expandNFT": "View",
Expand Down
4 changes: 4 additions & 0 deletions source/views/Extension/Popup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import ClockError from './Views/ClockError';
import Network from './Views/Network';
import NetworkCreation from './Views/NetworkCreation';
import ImportWallet from './Views/ImportWallet';
import ImportPemFile from './Views/ImportPemFile';
import ImportPrivateKey from './Views/ImportPrivateKey';

const Popup = ({ initialRoute }) => (
<Router initialRouteName={initialRoute}>
Expand All @@ -38,6 +40,8 @@ const Popup = ({ initialRoute }) => (
{/* <Route name="swap" component={Swap} /> */}
<Route name="clockError" component={ClockError} />
<Route name="import-wallet" component={ImportWallet} />
<Route name="import-pem-file" component={ImportPemFile} />
<Route name="import-private-key" component={ImportPrivateKey} />
<Route name="send" component={Send} />
<Route name="contacts" component={Contacts} />
<Route name="error" component={ErrorScreen} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ const useSteps = () => {
const steps = [
{
component: <Step1 handleChangeStep={handleChangeStep} setUserPemFile={setUserPemFile} userPemFile={userPemFile} />,
left: leftButton(() => handleClose()),
left: leftButton(() => navigator.navigate('import-wallet')),
right: rightButton,
center: `${t("importPem.importPEMfile")}`,
center: `${t("importWallet.importWallet")}`,
},
{
component: <Step2
handleClose={handleClose}
userPemFile={userPemFile}
/>,
right: rightButton,
center: `${t("importPem.walletDetails")}`,
center: `${t("importWallet.importWallet")}`,
},
];

Expand Down
21 changes: 21 additions & 0 deletions source/views/Extension/Views/ImportPemFile/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { Layout, Header } from '@components';
import useSteps from './hooks/useSteps';

const ImportWallet = () => {
const {
component,
left,
right,
center,
} = useSteps();

return (
<Layout>
<Header left={left} center={center} right={right} />
{component}
</Layout>
);
};

export default ImportWallet;
76 changes: 76 additions & 0 deletions source/views/Extension/Views/ImportPrivateKey/Steps/Step1.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { useState, useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next";
import useStyles from "../styles";
import { Typography, Grid } from "@material-ui/core";
import { Container, Button, TextInput, FormItem, UserIcon } from "@components";
import { HANDLER_TYPES, sendMessage } from "@background/Keyring";

const Step1 = ({ handleChangeStep, setPrivateKey, privateKey }) => {
const { t } = useTranslation();
const classes = useStyles();

const [loading, setLoading] = useState(false);
const [disabled, setDisabled] = useState(true);
const [invalidPem, setInvalidPem] = useState(null);

const handlePrivateKey = (e) => {
setLoading(true);
setPrivateKey(e.target.value);
sendMessage(
{
type: HANDLER_TYPES.VALIDATE_PEM,
params: {
pem: e.target.value
},
},
(a) => {
if (a) {
setDisabled(false);
setInvalidPem(false);
setLoading(false);
} else {
setInvalidPem(true);
setLoading(false);
setDisabled(true);
}
},
);
}

return (
<Container>
<Grid container spacing={2}>
<Grid item xs={12}>
<FormItem
label={`${t("importPrivateKey.privateKey")}`}
smallLabel
component={
<TextInput
fullWidth
value={privateKey}
onChange={(e) => handlePrivateKey(e)}
type="text"
data-testid="import-private-key-fill"
error={invalidPem}
/>
}
/>
{invalidPem && <Typography variant="body2" color="error">{`${t("importPrivateKey.invalidString")}`}</Typography>}
</Grid>
<Grid item xs={12}>
<Button
variant="rainbow"
value={t("common.continue")}
onClick={() => handleChangeStep(1)}
loading={loading}
disabled={disabled}
fullWidth
data-testid="add-button"
/>
</Grid>
</Grid>
</Container>
);
};

export default Step1;
118 changes: 118 additions & 0 deletions source/views/Extension/Views/ImportPrivateKey/Steps/Step2.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { Container, Button, TextInput, FormItem, UserIcon } from "@components";
import Grid from "@material-ui/core/Grid";
import useStyles from "../styles";
import React, { useState } from "react";
import { useRouter } from "@components/Router";
import { HANDLER_TYPES, sendMessage } from "@background/Keyring";
import Picker from "emoji-picker-react";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";

const Step2 = ({ privateKey }) => {
const { t } = useTranslation();

const [loading, setLoading] = useState(false);
const [disabled, setDisabled] = useState(true);
const [openEmojis, setOpenEmojis] = useState(false);
const [walletName, setWalletName] = useState(""); // add deafault wallet name, for example the next wallet not used number
const [currentEmoji, setCurrentEmoji] = useState("😎"); // add default emoji, not used in other wallets
const [openEmojiSelector, setOpenEmojiSelector] = useState(false);

const { navigator } = useRouter();

const classes = useStyles();

useEffect(() => {
if (walletName && walletName !== "") {
setDisabled(false);
} else {
setDisabled(true);
}
}, [currentEmoji, walletName]);

const onEmojiClick = (_event, emojiObject) => {
setCurrentEmoji(emojiObject.emoji);
setOpenEmojis(false);
setOpenEmojiSelector(false);
};

const createImportedAccount = () => {
setLoading(true);
sendMessage(
{
type: HANDLER_TYPES.IMPORT_PEM_ACCOUNT,
params: { icon: currentEmoji, name: walletName, pem: privateKey },
},
() => {},
);
setLoading(false);
navigator.navigate("home");
};


return (
<Container>
<Grid container spacing={2}>
<Grid item xs={12}>
<div className={classes.chooseEmojiContainer}>
<UserIcon icon={currentEmoji} size="big" />
<Button
variant="primary"
value={t("importPem.editWalletPic")}
onClick={() => setOpenEmojiSelector(!openEmojiSelector)}
style={{
minWidth: 115,
height: 24,
borderRadius: 6,
}}
/>
{openEmojiSelector && (
<Picker
pickerStyle={{
height: 190,
width: "auto",
position: "absolute",
top: 180,
left: 40,
right: 40,
zIndex: 500,
}}
onEmojiClick={onEmojiClick}
native
disableSearchBar
groupVisibility={{
recently_used: false,
flags: false,
}}
/>
)}
</div>
<FormItem
smallLabel
label={t("common.name")}
className={classes.formItem}
component={
<TextInput
fullWidth
onChange={(e) => setWalletName(e.target.value.trim())}
type="text"
// error={}
/>
}
/>
<Button
variant="rainbow"
value={t("common.save")}
onClick={createImportedAccount}
loading={loading}
disabled={disabled}
fullWidth
data-testid="add-button"
/>
</Grid>
</Grid>
</Container>
);
};

export default Step2;
44 changes: 44 additions & 0 deletions source/views/Extension/Views/ImportPrivateKey/hooks/useSteps.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useState } from 'react';
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);
const { navigator } = useRouter();
const { t } = useTranslation();

const [privateKey, setPrivateKey] = useState(null);

const handleChangeStep = (index) => setStep(index);
const handleClose = () => navigator.navigate('home');

const leftButton = (onClick) => <LinkButton value={t('common.back')} onClick={onClick} startIcon={BackIcon} />;
const rightButton = <LinkButton value={t('common.close')} onClick={handleClose} />;



const steps = [
{
component: <Step1 handleChangeStep={handleChangeStep} setPrivateKey={setPrivateKey} privateKey={privateKey} />,
left: leftButton(() => navigator.navigate('import-wallet')),
right: rightButton,
center: `${t("importWallet.importWallet")}`,
},
{
component: <Step2
handleClose={handleClose}
privateKey={privateKey}
/>,
right: rightButton,
center: `${t("importWallet.importWallet")}`,
},
];

return steps[step];
};

export default useSteps;
21 changes: 21 additions & 0 deletions source/views/Extension/Views/ImportPrivateKey/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { Layout, Header } from '@components';
import useSteps from './hooks/useSteps';

const ImportPrivateKey = () => {
const {
component,
left,
right,
center,
} = useSteps();

return (
<Layout>
<Header left={left} center={center} right={right} />
{component}
</Layout>
);
};

export default ImportPrivateKey;
Loading

0 comments on commit 7f3ff23

Please sign in to comment.