138 lines
5.1 KiB
TypeScript
138 lines
5.1 KiB
TypeScript
import { useRef, useState } from "react";
|
|
import { NetworkOptions } from "./NetworkOptions";
|
|
import { getAddress } from "viem";
|
|
import { Address } from "viem";
|
|
import { useAccount, useDisconnect } from "wagmi";
|
|
import {
|
|
ArrowLeftOnRectangleIcon,
|
|
ArrowTopRightOnSquareIcon,
|
|
ArrowsRightLeftIcon,
|
|
CheckCircleIcon,
|
|
ChevronDownIcon,
|
|
DocumentDuplicateIcon,
|
|
EyeIcon,
|
|
QrCodeIcon,
|
|
} from "@heroicons/react/24/outline";
|
|
import { BlockieAvatar } from "~~/components/scaffold-eth";
|
|
import { useCopyToClipboard, useOutsideClick } from "~~/hooks/scaffold-eth";
|
|
import { getTargetNetworks } from "~~/utils/scaffold-eth";
|
|
import { isENS } from "~~/utils/scaffold-eth/common";
|
|
|
|
const BURNER_WALLET_ID = "burnerWallet";
|
|
|
|
const allowedNetworks = getTargetNetworks();
|
|
|
|
type AddressInfoDropdownProps = {
|
|
address: Address;
|
|
blockExplorerAddressLink: string | undefined;
|
|
displayName: string;
|
|
ensAvatar?: string;
|
|
};
|
|
|
|
export const AddressInfoDropdown = ({
|
|
address,
|
|
ensAvatar,
|
|
displayName,
|
|
blockExplorerAddressLink,
|
|
}: AddressInfoDropdownProps) => {
|
|
const { disconnect } = useDisconnect();
|
|
const { connector } = useAccount();
|
|
const checkSumAddress = getAddress(address);
|
|
|
|
const { copyToClipboard: copyAddressToClipboard, isCopiedToClipboard: isAddressCopiedToClipboard } =
|
|
useCopyToClipboard();
|
|
const [selectingNetwork, setSelectingNetwork] = useState(false);
|
|
const dropdownRef = useRef<HTMLDetailsElement>(null);
|
|
|
|
const closeDropdown = () => {
|
|
setSelectingNetwork(false);
|
|
dropdownRef.current?.removeAttribute("open");
|
|
};
|
|
|
|
useOutsideClick(dropdownRef, closeDropdown);
|
|
|
|
return (
|
|
<>
|
|
<details ref={dropdownRef} className="dropdown dropdown-end leading-3">
|
|
<summary className="btn btn-secondary btn-sm pl-0 pr-2 shadow-md dropdown-toggle gap-0 h-auto!">
|
|
<BlockieAvatar address={checkSumAddress} size={30} ensImage={ensAvatar} />
|
|
<span className="ml-2 mr-1">
|
|
{isENS(displayName) ? displayName : checkSumAddress?.slice(0, 6) + "..." + checkSumAddress?.slice(-4)}
|
|
</span>
|
|
<ChevronDownIcon className="h-6 w-4 ml-2 sm:ml-0" />
|
|
</summary>
|
|
<ul className="dropdown-content menu z-2 p-2 mt-2 shadow-center shadow-accent bg-base-200 rounded-box gap-1">
|
|
<NetworkOptions hidden={!selectingNetwork} />
|
|
<li className={selectingNetwork ? "hidden" : ""}>
|
|
<div
|
|
className="h-8 btn-sm rounded-xl! flex gap-3 py-3 cursor-pointer"
|
|
onClick={() => copyAddressToClipboard(checkSumAddress)}
|
|
>
|
|
{isAddressCopiedToClipboard ? (
|
|
<>
|
|
<CheckCircleIcon className="text-xl font-normal h-6 w-4 ml-2 sm:ml-0" aria-hidden="true" />
|
|
<span className="whitespace-nowrap">Copied!</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<DocumentDuplicateIcon className="text-xl font-normal h-6 w-4 ml-2 sm:ml-0" aria-hidden="true" />
|
|
<span className="whitespace-nowrap">Copy address</span>
|
|
</>
|
|
)}
|
|
</div>
|
|
</li>
|
|
<li className={selectingNetwork ? "hidden" : ""}>
|
|
<label htmlFor="qrcode-modal" className="h-8 btn-sm rounded-xl! flex gap-3 py-3">
|
|
<QrCodeIcon className="h-6 w-4 ml-2 sm:ml-0" />
|
|
<span className="whitespace-nowrap">View QR Code</span>
|
|
</label>
|
|
</li>
|
|
<li className={selectingNetwork ? "hidden" : ""}>
|
|
<button className="h-8 btn-sm rounded-xl! flex gap-3 py-3" type="button">
|
|
<ArrowTopRightOnSquareIcon className="h-6 w-4 ml-2 sm:ml-0" />
|
|
<a
|
|
target="_blank"
|
|
href={blockExplorerAddressLink}
|
|
rel="noopener noreferrer"
|
|
className="whitespace-nowrap"
|
|
>
|
|
View on Block Explorer
|
|
</a>
|
|
</button>
|
|
</li>
|
|
{allowedNetworks.length > 1 ? (
|
|
<li className={selectingNetwork ? "hidden" : ""}>
|
|
<button
|
|
className="h-8 btn-sm rounded-xl! flex gap-3 py-3"
|
|
type="button"
|
|
onClick={() => {
|
|
setSelectingNetwork(true);
|
|
}}
|
|
>
|
|
<ArrowsRightLeftIcon className="h-6 w-4 ml-2 sm:ml-0" /> <span>Switch Network</span>
|
|
</button>
|
|
</li>
|
|
) : null}
|
|
{connector?.id === BURNER_WALLET_ID ? (
|
|
<li>
|
|
<label htmlFor="reveal-burner-pk-modal" className="h-8 btn-sm rounded-xl! flex gap-3 py-3 text-error">
|
|
<EyeIcon className="h-6 w-4 ml-2 sm:ml-0" />
|
|
<span>Reveal Private Key</span>
|
|
</label>
|
|
</li>
|
|
) : null}
|
|
<li className={selectingNetwork ? "hidden" : ""}>
|
|
<button
|
|
className="menu-item text-error h-8 btn-sm rounded-xl! flex gap-3 py-3"
|
|
type="button"
|
|
onClick={() => disconnect()}
|
|
>
|
|
<ArrowLeftOnRectangleIcon className="h-6 w-4 ml-2 sm:ml-0" /> <span>Disconnect</span>
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</details>
|
|
</>
|
|
);
|
|
};
|