Skip to content

Commit

Permalink
Add verification flow
Browse files Browse the repository at this point in the history
  • Loading branch information
OKendigelyan committed Sep 3, 2024
1 parent 5841c08 commit 7554978
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 46 deletions.
5 changes: 4 additions & 1 deletion apps/web/src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ export { default as ChevronDownIcon } from "./chevron-down.svg";
export { default as ChevronRightIcon } from "./chevron-right.svg";
export { default as CloseIcon } from "./close.svg";
export { default as CodeSandboxIcon } from "./code-sandbox.svg";
export { default as CoinIcon } from "./coin.svg";
export { default as ContactIcon } from "./contact-s.svg";
export { default as ContractIcon } from "./contract.svg";
export { default as CopyIcon } from "./copy.svg";
export { default as CoinIcon } from "./coin.svg";
export { default as CrossedCircleIcon } from "./crossed-circle.svg";
export { default as DelegateIcon } from "./delegate-s.svg";
export { default as DownloadIcon } from "./download.svg";
Expand Down Expand Up @@ -42,10 +42,12 @@ export { default as MenuIcon } from "./menu.svg";
export { default as MoonIcon } from "./moon.svg";
export { default as MultisigIcon } from "./multisig.svg";
export { default as OutgoingArrowIcon } from "./outgoing-arrow.svg";
export { default as PencilIcon } from "./pencil.svg";
export { default as PlusIcon } from "./plus.svg";
export { default as PyramidIcon } from "./pyramid.svg";
export { default as RadioIcon } from "./radio.svg";
export { default as RedditIcon } from "./reddit.svg";
export { default as ScanIcon } from "./scan.svg";
export { default as SearchIcon } from "./search.svg";
export { default as SelectorIcon } from "./selector.svg";
export { default as SettingsIcon } from "./settings.svg";
Expand All @@ -60,6 +62,7 @@ export { default as UserIcon } from "./user.svg";
export { default as UserPlusIcon } from "./user-plus.svg";
export { default as VerifiedIcon } from "./verified.svg";
export { default as WalletIcon } from "./wallet.svg";
export { default as WindowCloseIcon } from "./window-close.svg";
export { TokenIcon } from "./TokenIcon";

import CloseIcon from "./close.svg";
Expand Down
5 changes: 5 additions & 0 deletions apps/web/src/assets/icons/pencil.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions apps/web/src/assets/icons/scan.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions apps/web/src/assets/icons/window-close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/web/src/components/AccountCard/AccountBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ArrowDownLeftIcon, WalletIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";
import { AccountInfoModal } from "../AccountSelectorModal";
import { IconButtonWithText } from "../IconButtonWithText";
import { useIsAccountVerified } from "../Onboarding/useIsAccountVerified";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow/useIsAccountVerified";

export const AccountBalance = () => {
const color = useColor();
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/AccountCard/SendTezButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useCurrentAccount } from "@umami/state";

import { ArrowUpRightIcon } from "../../assets/icons";
import { IconButtonWithText } from "../IconButtonWithText/IconButtonWithText";
import { useIsAccountVerified } from "../Onboarding/useIsAccountVerified";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow/useIsAccountVerified";
import { FormPage as SendTezFormPage } from "../SendFlow/Tez/FormPage";

export const SendTezButton = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { useColor } from "../../styles/useColor";
import { AccountTile } from "../AccountTile";
import { ModalCloseButton } from "../CloseButton";
import { OnboardOptionsModal } from "../Onboarding/OnboardOptions";
import { useIsAccountVerified } from "../Onboarding/useIsAccountVerified";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow/useIsAccountVerified";

export const AccountSelectorModal = () => {
const accounts = useImplicitAccounts();
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/EmptyMessage/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { EmptyMessage } from "./EmptyMessage";
export { VerifyMessage } from "./VerifyMessage";
export type { EmptyMessageProps } from "./EmptyMessage";
2 changes: 1 addition & 1 deletion apps/web/src/components/Menu/AdvancedMenu/AdvancedMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDynamicDrawerContext } from "@umami/components";

import { AlertCircleIcon, LockIcon, RadioIcon } from "../../../assets/icons";
import { useIsAccountVerified } from "../../Onboarding/useIsAccountVerified";
import { useIsAccountVerified } from "../../Onboarding/VerificationFlow/useIsAccountVerified";
import { ChangePasswordMenu } from "../ChangePasswordMenu/ChangePasswordMenu";
import { ErrorLogsMenu } from "../ErrorLogsMenu/ErrorLogsMenu";
import { GenericMenu } from "../GenericMenu";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
UserPlusIcon,
} from "../../assets/icons";
import { OnboardOptionsModal } from "../Onboarding/OnboardOptions";
import { useIsAccountVerified } from "../Onboarding/useIsAccountVerified";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow/useIsAccountVerified";

export const Menu = () => {
const { openWith: openModal } = useDynamicModalContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type FormFields = {
type Mode = "mnemonic" | "secret_key" | "new_mnemonic";

type SetupPasswordProps = {
mode: Mode;
mode?: Mode;
handleSubmit?: (password: string) => void;
};

Expand Down Expand Up @@ -102,14 +102,16 @@ export const SetupPassword = ({ mode, handleSubmit }: SetupPasswordProps) => {
});
break;
}
default:
break;
}

return onClose();
});

const icon = isNewMnemonic ? UserIcon : LockIcon;
const title = isNewMnemonic ? "Create Password" : "Almost there";
const buttonLabel = isNewMnemonic ? "Create Account" : "Import Wallet";
const title = mode ? (isNewMnemonic ? "Create Password" : "Almost there") : "Confirm password";
const buttonLabel = mode ? (isNewMnemonic ? "Create Account" : "Import Wallet") : "Confirm";

return (
<ModalContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import {
Text,
} from "@chakra-ui/react";

import { CopyIcon, KeyIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";
import { ModalBackButton } from "../BackButton";
import { ModalCloseButton } from "../CloseButton";
import { CopyButton } from "../CopyButton";
import { CopyIcon, KeyIcon } from "../../../assets/icons";
import { useColor } from "../../../styles/useColor";
import { ModalBackButton } from "../../BackButton";
import { ModalCloseButton } from "../../CloseButton";
import { CopyButton } from "../../CopyButton";

type CopySeedphraseModalProps = {
seedPhrase: string;
Expand All @@ -33,7 +33,7 @@ export const CopySeedphraseModal = ({ seedPhrase }: CopySeedphraseModalProps) =>
<ModalBackButton />
<ModalCloseButton />
<Center flexDirection="column" gap="12px">
<Icon as={KeyIcon} width="24px" height="24px" marginBottom="4px" color={color("blue")} />
<Icon as={KeyIcon} boxSize="24px" marginBottom="4px" color={color("blue")} />
<Heading size="xl">Import Wallet</Heading>
<Text width="full" color={color("700")} fontWeight="400" textAlign="center" size="md">
Record these 24 words in order to restore your wallet in the future
Expand All @@ -42,23 +42,28 @@ export const CopySeedphraseModal = ({ seedPhrase }: CopySeedphraseModalProps) =>
</ModalHeader>

<ModalBody>
<Grid gridRowGap="16px" gridColumnGap="12px" gridTemplateColumns="repeat(3, 1fr)">
<Grid
gridRowGap="16px"
gridColumnGap={{ base: "8px", md: "12px" }}
gridTemplateColumns="repeat(3, 1fr)"
>
{words.map((word, index) => (
<GridItem
key={index}
as={Flex}
alignItems="center"
gap="8px"
padding="12px 16px"
gap={{ base: "6px", lg: "8px" }}
maxHeight={{ base: "34px", lg: "48px" }}
padding={{ base: "10px 12px", lg: "12px 16px" }}
borderWidth="1.5px"
borderStyle="dashed"
borderColor={color("300")}
borderRadius="full"
>
<Text color={color("300")} fontSize="lg">
<Text color={color("300")} fontSize={{ base: "xs", lg: "lg" }}>
{String(index + 1).padStart(2, "0")}.
</Text>
<Text fontSize="lg" fontWeight="medium">
<Text fontSize={{ base: "xs", lg: "lg" }} fontWeight="medium">
{word}
</Text>
</GridItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
Box,
Button,
Center,
Flex,
Heading,
Icon,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
Text,
VStack,
} from "@chakra-ui/react";

import {
AlertIcon,
EyeOffIcon,
PencilIcon,
ScanIcon,
WindowCloseIcon,
} from "../../../assets/icons";
import { useColor } from "../../../styles/useColor";
import { ModalCloseButton } from "../../CloseButton";

export const ImportantNoticeModal = () => {
const color = useColor();

return (
<ModalContent>
<ModalHeader>
<Center flexDirection="column" gap="12px">
<Icon as={AlertIcon} boxSize="24px" marginBottom="4px" color={color("blue")} />
<Heading size="xl">Important Notice</Heading>
<Text width="full" color={color("700")} fontWeight="400" textAlign="center" size="md">
Please read the following before you continue to see your secret Seed Phrase.
</Text>
</Center>
<ModalCloseButton />
</ModalHeader>
<ModalBody>
<VStack align="stretch" spacing="12px">
<Flex
alignItems="center"
gap="16px"
padding="12px 24px"
color={color("white")}
background={color("100")}
borderRadius="6px"
>
<Icon as={PencilIcon} boxSize="24px" color={color("300")} />
<Text color={color("900")}>Write down your seed phrase and store it safely</Text>
</Flex>

<Box padding="12px" background={color("700")} borderRadius="6px">
<Flex alignItems="center">
<Icon as={EyeOffIcon} marginRight="8px" />
<Text>Ensure no one else can see it</Text>
</Flex>
</Box>
<Box padding="12px" background={color("700")} borderRadius="6px">
<Flex alignItems="center">
<Icon as={WindowCloseIcon} marginRight="8px" />
<Text>Do not store it digitally</Text>
</Flex>
</Box>
<Box padding="12px" background={color("700")} borderRadius="6px">
<Flex alignItems="center">
<Icon as={ScanIcon} marginRight="8px" />
<Text>Avoid taking screenshots</Text>
</Flex>
</Box>
</VStack>
</ModalBody>
<ModalFooter>
<Button width="full" variant="primary">
Next
</Button>
</ModalFooter>
</ModalContent>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
Text,
} from "@chakra-ui/react";

import { AlertIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";
import { ModalCloseButton } from "../CloseButton";
import { AlertIcon } from "../../../assets/icons";
import { useColor } from "../../../styles/useColor";
import { ModalCloseButton } from "../../CloseButton";

// TODO: Replace with actual copy paste
const accordionItems = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { VerificationInfoModal } from "./VerificationInfoModal";
import { VerifyMessage } from "./VerifyMessage";
import { dynamicModalContextMock, render, screen, userEvent } from "../../testUtils";
import { VerificationInfoModal } from "../Onboarding/VerificationInfoModal";
import { dynamicModalContextMock, render, screen, userEvent } from "../../../testUtils";

describe("<VerifyMessage />", () => {
it("renders correctly", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import { Flex, Link } from "@chakra-ui/react";
import { useDynamicModalContext } from "@umami/components";
import { type MnemonicAccount } from "@umami/core";
import { useCurrentAccount, useGetDecryptedMnemonic } from "@umami/state";
import { useAsyncActionHandler, useCurrentAccount, useGetDecryptedMnemonic } from "@umami/state";

import { EmptyMessage, type EmptyMessageProps } from "./EmptyMessage";
import { useColor } from "../../styles/useColor";
import { CopySeedphraseModal } from "../Onboarding/CopySeedphraseModal";
import { SetupPassword } from "../Onboarding/SetupPassword";
import { VerificationInfoModal } from "../Onboarding/VerificationInfoModal";
import { CopySeedphraseModal } from "./CopySeedphraseModal";
import { ImportantNoticeModal } from "./ImportantNoticeModal";
import { VerificationInfoModal } from "./VerificationInfoModal";
import { useColor } from "../../../styles/useColor";
import { EmptyMessage, type EmptyMessageProps } from "../../EmptyMessage";
import { SetupPassword } from "../SetupPassword";

export const VerifyMessage = ({ ...props }: Omit<EmptyMessageProps, "title">) => {
const { openWith } = useDynamicModalContext();
const currentAccount = useCurrentAccount() as MnemonicAccount;
const color = useColor();
const getDecryptedMnemonic = useGetDecryptedMnemonic();
const { handleAsyncAction } = useAsyncActionHandler();

const handleDeriveSeedphraseModal = async (password: string) => {
const mnemonic = await getDecryptedMnemonic(currentAccount, password);
const handleDeriveSeedphraseModal = async (password: string) =>
handleAsyncAction(async () => {
const mnemonic = await getDecryptedMnemonic(currentAccount, password);

return openWith(<CopySeedphraseModal seedPhrase={mnemonic} />);
};
return openWith(<ImportantNoticeModal />, { size: "xl" });
return openWith(<CopySeedphraseModal seedPhrase={mnemonic} />);
});

return (
<Flex alignItems="center" flexDirection="column" margin="auto" data-testid="verify-message">
<EmptyMessage
cta="Verify Now"
onClick={() =>
openWith(<SetupPassword handleSubmit={handleDeriveSeedphraseModal} mode="mnemonic" />)
}
onClick={() => openWith(<SetupPassword handleSubmit={handleDeriveSeedphraseModal} />)}
subtitle={
"Please verify your account, to unlock all features\n and keep your account secure."
}
Expand Down
5 changes: 5 additions & 0 deletions apps/web/src/components/Onboarding/VerificationFlow/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { CopySeedphraseModal } from "./CopySeedphraseModal";
export { VerificationInfoModal } from "./VerificationInfoModal";
export { VerifyMessage } from "./VerifyMessage";
export { useIsAccountVerified } from "./useIsAccountVerified";
export { ImportantNoticeModal } from "./ImportantNoticeModal";
2 changes: 1 addition & 1 deletion apps/web/src/components/ViewOverlay/ViewOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Box, Icon } from "@chakra-ui/react";

import { CoinIcon, LockIcon, PyramidIcon, WalletIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";
import { useIsAccountVerified } from "../Onboarding/useIsAccountVerified";
import { useIsAccountVerified } from "../Onboarding/VerificationFlow/useIsAccountVerified";

type ViewOverlayProps = {
iconType: "activity" | "earn" | "nfts" | "tokens";
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/views/Activity/Activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { type UIEvent, useRef } from "react";

import loadingDots from "../../assets/loading-dots.gif";
import loadingWheel from "../../assets/loading-wheel.gif";
import { EmptyMessage, VerifyMessage } from "../../components/EmptyMessage";
import { useIsAccountVerified } from "../../components/Onboarding/useIsAccountVerified";
import { EmptyMessage } from "../../components/EmptyMessage";
import { VerifyMessage } from "../../components/Onboarding/VerificationFlow";
import { useIsAccountVerified } from "../../components/Onboarding/VerificationFlow/useIsAccountVerified";
import { OperationTile } from "../../components/OperationTile";
import { ViewOverlay } from "../../components/ViewOverlay/ViewOverlay";
import { useColor } from "../../styles/useColor";
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/views/NFTs/NFTs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { range } from "lodash";
import { NFTCard } from "./NFTCard";
import { NFTDrawer } from "./NFTDrawer";
import { NFTFilter, useNFTFilter } from "./NFTFilter";
import { EmptyMessage, VerifyMessage } from "../../components/EmptyMessage";
import { useIsAccountVerified } from "../../components/Onboarding/useIsAccountVerified";
import { EmptyMessage } from "../../components/EmptyMessage";
import { VerifyMessage } from "../../components/Onboarding/VerificationFlow";
import { useIsAccountVerified } from "../../components/Onboarding/VerificationFlow/useIsAccountVerified";
import { ViewOverlay } from "../../components/ViewOverlay/ViewOverlay";
import { useColor } from "../../styles/useColor";

Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/views/Tokens/Tokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { fullId } from "@umami/core";
import { useCurrentAccount, useGetAccountAllTokens } from "@umami/state";

import { Token } from "./Token";
import { EmptyMessage, VerifyMessage } from "../../components/EmptyMessage";
import { useIsAccountVerified } from "../../components/Onboarding/useIsAccountVerified";
import { EmptyMessage } from "../../components/EmptyMessage";
import { useIsAccountVerified } from "../../components/Onboarding/VerificationFlow/useIsAccountVerified";
import { VerifyMessage } from "../../components/Onboarding/VerificationFlow/VerifyMessage";
import { ViewOverlay } from "../../components/ViewOverlay/ViewOverlay";

export const Tokens = () => {
Expand Down

1 comment on commit 7554978

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Title Lines Statements Branches Functions
apps/desktop Coverage: 84%
83.95% (1789/2131) 79.09% (840/1062) 78.57% (451/574)
apps/web Coverage: 84%
83.95% (1789/2131) 79.09% (840/1062) 78.57% (451/574)
packages/components Coverage: 96%
96.89% (125/129) 98.07% (51/52) 84.21% (32/38)
packages/core Coverage: 82%
83.05% (196/236) 73.55% (89/121) 82.14% (46/56)
packages/crypto Coverage: 100%
100% (28/28) 100% (3/3) 100% (5/5)
packages/data-polling Coverage: 98%
96.55% (140/145) 95.45% (21/22) 92.85% (39/42)
packages/multisig Coverage: 98%
98.4% (123/125) 89.47% (17/19) 100% (33/33)
packages/social-auth Coverage: 100%
100% (21/21) 100% (11/11) 100% (3/3)
packages/state Coverage: 83%
83.36% (772/926) 80% (164/205) 78.43% (291/371)
packages/tezos Coverage: 86%
85.57% (89/104) 89.47% (17/19) 82.75% (24/29)
packages/tzkt Coverage: 86%
84.05% (58/69) 81.25% (13/16) 76.92% (30/39)

Please sign in to comment.