import { useEffect, useRef, useState } from "react"; import { CSSTransition } from "react-transition-group"; import Icon from "./../../atoms/Icon"; import { faChevronDown, faChevronUp, faCircleInfo, faGlobe, faQrcode, faWarning, faXmark, } from "@fortawesome/free-solid-svg-icons"; import "./index.css"; import AccountComponent from "./Account"; import Tabs from "../../atoms/Tabs"; import Dropdown from "../../atoms/Dropdown/Dropdown"; import DropdownItem from "../../atoms/Dropdown/DropdownItem"; import Button from "../../atoms/Button"; import { localizedStrings as strings } from "../../../l10n/l10n"; import Input from "../../atoms/Input"; import Tooltip from "../../atoms/Tooltip"; import Loading from "../../atoms/Loading"; import CopyButton from "../CopyButton"; import Text from "../../atoms/Text"; import Form from "../../atoms/Form"; import Label from "../../atoms/Label"; import Checkbox from "../../atoms/Checkbox"; import Tag from "../../atoms/Tag"; export type Extension = { name: string; displayName: string; link: string; selected: boolean; installed: boolean; isSnap?: boolean; icon?: JSX.Element; chromeExtensionLink?: string; firefoxExtensionLink?: string; }; export type Account = { name?: string; address: string; evmAddress?: string; source?: string; isEvmClaimed?: boolean; }; export type Network = "mainnet" | "testnet"; export type Language = "en" | "hi"; export interface AccountCreationData { address: string; seed: string; } enum ImportState { NONE, SEED, JSON, } export interface Props { isOpen: boolean; availableExtensions?: Extension[]; selExtName?: string; accounts?: Account[]; selectedAccount?: Account | null | undefined; selectedNetwork?: Network; availableNetworks?: Network[]; showSnapOptions?: boolean; onClose?: (...args: any[]) => any; onExtensionSelect?: (name: string) => any; onSelect?: (...args: any[]) => any; onRename?: (address: string, newName: string) => any; onExport?: (address: string, password: string) => any; onImport?: (...args: any[]) => any; onForget?: (address: string) => any; onNetworkSelect?: (network: Network) => any; onLanguageSelect?: (language: Language) => any; onUpdateMetadata?: (network: Network) => any; onStartAccountCreation?: () => Promise; onConfirmAccountCreation?: (seed: string, name: string) => any; handleWalletConnect?:()=>Promise; className?: string; } function AccountSelector({ isOpen, availableExtensions, selExtName, accounts, selectedAccount, availableNetworks, selectedNetwork, showSnapOptions, onExtensionSelect, onClose, onSelect, onRename, onExport, onImport, onForget, onNetworkSelect, onLanguageSelect, onUpdateMetadata, onStartAccountCreation, onConfirmAccountCreation, handleWalletConnect, className, }: Props): JSX.Element { const wrapper = useRef(null); const isSelected = (account: Account): boolean => { return ( !!selectedAccount?.address && account.address === selectedAccount.address && account.source === selectedAccount.source ); }; const select = (account: Account) => { if (onSelect) onSelect(account); }; const opened = () => (document.body.style.overflow = "hidden"); const closed = () => (document.body.style.overflow = ""); const [isExtensionDropdownOpen, setExtensionDropdown] = useState(false); const [isLanguageDropdownOpen, setLanguageDropdown] = useState(false); const [isCreateDropdownOpen, setCreateDropdown] = useState(false); const [isImportDropdownOpen, setImportDropdown] = useState(false); const [extensions, setExtensions] = useState(); const [selectedExtension, setSelectedExtension] = useState(); const [accountCreationData, setAccountCreationData] = useState(); const [seedSaved, setSeedSaved] = useState(false); const [newName, setNewName] = useState(""); const [password, setPassword] = useState(""); const [submittedWithError, setSubmittedWithError] = useState(false); const [importState, setImportState] = useState(ImportState.NONE); const [importSeed, setImportSeed] = useState(""); const [importJson, setImportJson] = useState(""); useEffect(() => { if (availableExtensions?.length) { const selectedName = selExtName || availableExtensions[0].name; availableExtensions.forEach((extension) => { extension.selected = extension.name === selectedName; }); const selected = availableExtensions.find((extension) => extension.selected); setExtensions(availableExtensions); setSelectedExtension(selected); } else { setExtensions([]); setSelectedExtension(undefined); } }, [availableExtensions, selExtName]); const onExtensionClick = (extension: Extension) => { if (extension.selected) return; onExtensionSelect(extension.name); }; const closeAccountCreation = () => { setAccountCreationData(undefined); setNewName(""); setSubmittedWithError(false); setSeedSaved(false); setCreateDropdown(false); }; const onCreateClick = () => { if (newName?.length > 2 && seedSaved) { onConfirmAccountCreation(accountCreationData.seed, newName); closeAccountCreation(); } else { setSubmittedWithError(true); } }; const closeAccountImport = () => { setImportState(ImportState.NONE); setNewName(""); setPassword(""); setImportSeed(""); setImportJson(""); setSubmittedWithError(false); setImportDropdown(false); }; const onImportClick = () => { if (importState === ImportState.SEED) { if (!validSeed() || !(newName?.length > 2)) { setSubmittedWithError(true); return; } else { onImport({ name: newName, seed: importSeed }); closeAccountImport(); } } else if (importState === ImportState.JSON) { if (!validJson() || !password.length) { setSubmittedWithError(true); return; } else { onImport({ json: importJson, password }); closeAccountImport(); } } }; const validSeed = () => { return ( importSeed && (importSeed.trim().split(/\s+/).length === 12 || importSeed.trim().split(/\s+/).length === 24) ); }; const validJson = () => { try { JSON.parse(importJson); return true; } catch (e) { return false; } }; const getExtensionLink = (extension: Extension) => { const isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") > -1; if (isFirefox && extension.firefoxExtensionLink) { return extension.firefoxExtensionLink; } else if (extension.chromeExtensionLink) { return extension.chromeExtensionLink; } else { return extension.link; } } return (
{!!extensions && !!extensions.length && !!onExtensionSelect ? (
setExtensionDropdown(false)} position="bottomRight" className="uik-account-selector__extension-dropdown" > {extensions.map((extension, index) => ( onExtensionClick(extension)} className="uik-account-selector__extension-item" >
{extension.icon && extension.icon}
{extension.displayName} {extension.selected && ( )}
))}
) : (
{strings.select_account}
)} {!!onLanguageSelect && (
)} {!!selectedNetwork && !!onNetworkSelect && ( { return { value: val, text: strings[val] }; })} onChange={onNetworkSelect} /> )}
{!!showSnapOptions && (!extensions || selectedExtension?.isSnap) && (
{onStartAccountCreation && onConfirmAccountCreation && ( <>
) : ( )} )} {onImport && ( <> ) : ( <> {importState === ImportState.SEED ? ( <> setNewName(e.target.value)} /> setImportSeed(e.target.value) } /> ) : ( <> setImportJson(e.target.value) } /> setPassword(e.target.value)} /> )}
)} )} {onUpdateMetadata && !!selectedNetwork && (
)}
{!!accounts && !!accounts.length && accounts.map((account, index) => {return ( !isSelected(account)?<>: select(account)} onRename={ onRename ? (newName) => onRename(account.address, newName) : undefined } onExport={ onExport ? (exportPassword) => onExport(account.address, exportPassword) : undefined } onForget={ onForget ? () => onForget(account.address) : undefined } isSelected={isSelected(account)} showOptions={ !!showSnapOptions && (!extensions || selectedExtension?.isSnap) } /> )})}
{!!accounts && !!accounts.length ? accounts.map((account, index) => {return ( isSelected(account)?<>: select(account)} onRename={ onRename ? (newName) => onRename(account.address, newName) : undefined } onExport={ onExport ? (exportPassword) => onExport(account.address, exportPassword) : undefined } onForget={ onForget ? () => onForget(account.address) : undefined } isSelected={isSelected(account)} showOptions={ !!showSnapOptions && (!extensions || selectedExtension?.isSnap) } /> )}) :
{selectedExtension?.installed ? ( <>
{strings.no_accounts}
{strings.use_reef_chain_extension}
) : ( <>
{strings.no_wallet}
{selectedExtension?.displayName && (
{strings.install_wallet.split("{LINK}")[0]} {selectedExtension.displayName} {strings.install_wallet.split("{LINK}")[1]} {selectedExtension.name==="reef-wallet-connect" && handleWalletConnect?
:""}
)} )}
}
); }; export default AccountSelector;