Skip to content
This repository has been archived by the owner on Oct 15, 2023. It is now read-only.

Commit

Permalink
Merge branch 'feature/switch-chain' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
exrobbie committed Sep 7, 2023
2 parents 8a65e2c + 46ed4d1 commit 1b8be51
Show file tree
Hide file tree
Showing 24 changed files with 377 additions and 61 deletions.
3 changes: 3 additions & 0 deletions src/assets/icons/checkmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/error.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 src/assets/switch-chain-line.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: 7 additions & 1 deletion src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ browser.runtime.onMessage.addListener(async (msg, sender) => {
} else {
openWindow(`${msg.url}&tabId=${senderTabId}&origin=${msg.data.origin}&id=${id}`, windowWidth);
}

break;

case "switchChain":
console.log('Swith chain msg', msg);
const targetChainId = msg.data.chainId
openWindow(`${msg.url}&tabId=${senderTabId}&origin=${msg.data.origin}&id=${id}&targetChainId=${targetChainId}`, windowWidth);
break;

case "getChainConfig":
const chainConfig = getSelectedChainItem();
console.log("SO you see", chainConfig)
browser.tabs.sendMessage(Number(senderTabId), {
id,
isResponse: true,
Expand Down
11 changes: 2 additions & 9 deletions src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@ interface IProps extends Omit<ButtonProps, "type"> {
href?: string;
}

export default function Button({
onClick,
children,
loading,
disabled,
href,
...restProps
}: IProps) {
export default function Button({ onClick, children, loading, disabled, href, ...restProps }: IProps) {
const doClick = () => {
if (!loading && !disabled) {
onClick();
Expand All @@ -37,7 +30,7 @@ export default function Button({
_hover={{ bg: "brand.redDarken" }}
h="unset"
transition={"all 0.2s ease-in-out"}
_disabled={{ opacity: "0.5", cursor: "not-allowed" }}
_disabled={{ bg: "#898989", cursor: "not-allowed" }}
onClick={doClick}
rounded={"20px"}
lineHeight={"1"}
Expand Down
4 changes: 2 additions & 2 deletions src/components/ChainSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export default function ChainSelect() {
return (
<React.Fragment key={idx}>
{idx ? <MenuDivider /> : ""}
<MenuItem key={item.chainId} onClick={() => setSelectedChainId(item.chainId)}>
<MenuItem key={item.chainIdHex} onClick={() => setSelectedChainId(item.chainIdHex)}>
<Flex w="100%" align={"center"} justify={"space-between"}>
<Flex align={"center"} gap="2">
<Image src={item.icon} w="5" h="5" />
<Text data-testid={`text-chainname-${idx}`} fontWeight={"700"}>{item.chainName}</Text>
</Flex>
{item.chainId === selectedChainId && <Image src={IconChecked} w="5" h="5" />}
{item.chainIdHex === selectedChainId && <Image src={IconChecked} w="5" h="5" />}
</Flex>
</MenuItem>
</React.Fragment>
Expand Down
57 changes: 57 additions & 0 deletions src/components/ErrorModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { useState } from "react";
import { Modal, ModalOverlay, ModalContent, Text, Flex, Box, Image } from "@chakra-ui/react";
import IconError from "@src/assets/icons/error.svg";

export default function ErrorModal({ text, onClose, okText, cancelText, onOk, onCancel }: any) {
return (
<Modal isOpen={true} onClose={onClose} isCentered>
<ModalOverlay backdropFilter={"blur(7.5px)"} bg="rgba(137, 137, 137, 0.20)" />
<ModalContent
mx="20px"
p="5"
textAlign={"center"}
bg="#fff"
rounded="20px"
boxShadow={"0px 4px 4px 0px rgba(0, 0, 0, 0.25)"}
flexDir={"column"}
gap="5"
>
<Box>
<Image src={IconError} w="58px" h="58px" mx="auto" display={"block"} />
<Text color="#1e1e1e" fontWeight={"800"} fontSize="18px">
{text}
</Text>
</Box>

<Flex align={"center"}>
<Text
w="50%"
cursor={"pointer"}
onClick={onCancel}
fontSize={"16px"}
fontWeight={"800"}
color="brand.red"
>
{cancelText}
</Text>
<Text
w="50%"
cursor={"pointer"}
py="3"
fontSize={"16px"}
fontWeight={"800"}
bg="brand.red"
_hover={{
bg: "brand.redDarken",
}}
color="#fff"
rounded="20px"
onClick={onOk}
>
{okText}
</Text>
</Flex>
</ModalContent>
</Modal>
);
}
188 changes: 188 additions & 0 deletions src/components/SignModal/comp/SwitchChain.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import React, { useEffect, useState } from "react";
import { Box, Image, Flex, Text, Menu, MenuButton, MenuList, MenuItem, Tooltip, useDisclosure } from "@chakra-ui/react";
import SwitchNetworkLine from "@src/assets/switch-chain-line.svg";
import Button from "../../Button";
import useConfig from "@src/hooks/useConfig";
import IconChevronRight from "@src/assets/icons/chevron-right-red.svg";
import IconCheckmark from "@src/assets/icons/checkmark.svg";
import { InfoWrap, InfoItem } from "../index";
import { useChainStore } from "@src/store/chain";
import { useAddressStore } from "@src/store/address";
import { toShortAddress, getChainInfo } from "@src/lib/tools";
import useBrowser from "@src/hooks/useBrowser";
import ErrorModal from "@src/components/ErrorModal";
import config from "@src/config";

const ChainAvatar = ({ avatar }: any) => (
<Flex align="center" justify={"center"} bg="#fff" rounded="full" w="72px" h="72px">
<Image src={avatar} w="44px" h="44px" />
</Flex>
);

export default function ConnectDapp({ onConfirm, targetChainId }: any) {
const { selectedAddressItem } = useConfig();
const { selectedChainId } = useChainStore();
const { addressList, setSelectedAddress } = useAddressStore();
const { setSelectedChainId } = useChainStore();
const { title, address } = selectedAddressItem;
const [errorType, setErrorType] = useState(0);
const { navigate } = useBrowser();

const checkIfCanSwitch = () => {
const chainSupported = config.chainList.filter((item) => item.chainIdHex === targetChainId).length > 0;

const targetChainActivited = selectedAddressItem.activatedChains.includes(targetChainId);
const otherAccountsTargetChainActivited =
addressList.filter((item) => item.activatedChains.includes(targetChainId)).length > 0;

if (!chainSupported) {
setErrorType(1);
} else if (!targetChainActivited && otherAccountsTargetChainActivited) {
setErrorType(2);
} else if (!targetChainActivited && !otherAccountsTargetChainActivited) {
setErrorType(3);
}
};

const cancelSwitch = () => {
setErrorType(0);
window.close();
// throw new Error('User rejected switch network');
};

useEffect(() => {
checkIfCanSwitch();
}, []);

const canSwitch = selectedAddressItem.activatedChains.includes(targetChainId);

return (
<Box pt="5">
<Box textAlign={"center"}>
<Flex align="center" display={"inline-flex"} gap="1" mx="auto" mb="5" position={"relative"}>
<ChainAvatar avatar={getChainInfo(selectedChainId).icon} />
<Image src={SwitchNetworkLine} />
<ChainAvatar avatar={getChainInfo(targetChainId).icon} />
</Flex>
</Box>

<Box textAlign={"center"} mb="176px">
<Text fontSize={"20px"} fontWeight={"800"} mb="1">
Allow network switch?
</Text>
<Text fontWeight={"600"}>
This will switch the selected network within current dApp to{" "}
<Text color="#ee3f99" display={"inline"}>
{getChainInfo(targetChainId).name}
</Text>
.
</Text>
</Box>
<InfoWrap>
<InfoItem>
<Text>{title}:</Text>
<Text>
<Menu placement="bottom-end">
<MenuButton>
<Flex align={"center"}>
<Text color="brand.red" fontWeight={"500"}>
{toShortAddress(address, 5, 4)}
</Text>
<Image src={IconChevronRight} />
</Flex>
</MenuButton>
<MenuList maxW={"280px"} pt="4" pb="3" px="4">
<Text fontWeight={"800"} lineHeight={"1.25"} mb="3" color="#000">
Select an activated account on this network to continue
</Text>
{addressList.map((item) => (
<MenuItem key={item.address} px="0" py="3" borderTop={"1px solid #e6e6e6"}>
{item.activatedChains.includes(targetChainId) ? (
<Flex
align={"center"}
w="100%"
justify={"space-between"}
onClick={() => setSelectedAddress(item.address)}
>
<Flex gap="3" align="center">
<Text fontWeight={"800"}>{item.title}</Text>
<Text fontSize={"12px"} color="#898989">
{toShortAddress(item.address, 6, 4)}
</Text>
</Flex>
{item.address === selectedAddressItem.address && (
<Image src={IconCheckmark} />
)}
</Flex>
) : (
<Flex gap="3" align="center" color="#cececf" w="100%" h="100%">
<Text fontWeight={"800"}>{item.title}</Text>
<Text fontSize={"12px"}>{toShortAddress(item.address, 6, 4)}</Text>
</Flex>
)}
</MenuItem>
))}
</MenuList>
</Menu>
</Text>
</InfoItem>
</InfoWrap>
<Button
w="100%"
fontSize={"20px"}
py="4"
fontWeight={"800"}
mt="6"
disabled={!canSwitch}
onClick={onConfirm}
>
Switch network
</Button>

{errorType === 1 && (
<ErrorModal
text="Unfortunately, your selected network is not supported yet. Please try again later."
cancelText="Cancel"
onCancel={cancelSwitch}
onClose={() => {}}
okText="Back"
onOk={() => {
navigate("wallet");
}}
/>
)}

{errorType === 2 && (
<ErrorModal
text="Please activate your account or select an activated account on this network to continue"
cancelText="Other account"
onCancel={() => {
setErrorType(0);
}}
onClose={() => {
setErrorType(0);
}}
okText="Activate"
onOk={() => {
setSelectedChainId(targetChainId);
navigate("activate");
}}
/>
)}

{errorType === 3 && (
<ErrorModal
text="Please activate your account on this network to continue"
cancelText="Cancel"
onCancel={cancelSwitch}
onClose={() => {}}
okText="Activate"
onOk={() => {
setSelectedChainId(targetChainId);
navigate("activate");
}}
/>
)}
</Box>
);
}
Loading

0 comments on commit 1b8be51

Please sign in to comment.