"use client"; import { WalletIcon, ArrowsRightLeftIcon, XCircleIcon, ChevronDownIcon, BanknotesIcon, ChevronRightIcon, CheckIcon, } from "@heroicons/react/24/outline"; import { useWallet } from "@solana/wallet-adapter-react"; import { useWalletModal } from "@solana/wallet-adapter-react-ui"; import type { PublicKey } from "@solana/web3.js"; import clsx from "clsx"; import { useSelectedLayoutSegment } from "next/navigation"; import { type ComponentProps, type ReactNode, useCallback, useMemo, type ReactElement, } from "react"; import { MenuTrigger, SubmenuTrigger, Header, Collection, MenuItem as BaseMenuItem, } from "react-aria-components"; import { VPN_BLOCKED_SEGMENT } from "../../config/isomorphic"; import { StateType as ApiStateType, type States, useApi, } from "../../hooks/use-api"; import { StateType as DataStateType, useData } from "../../hooks/use-data"; import { useLogger } from "../../hooks/use-logger"; import { useNetwork } from "../../hooks/use-network"; import { usePrimaryDomain } from "../../hooks/use-primary-domain"; import { Button } from "../Button"; import { Menu, MenuItem, Section, Separator } from "../Menu"; import { Switch } from "../Switch"; import { TruncatedKey } from "../TruncatedKey"; const ONE_SECOND_IN_MS = 1000; const ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS; const REFRESH_INTERVAL = 1 * ONE_MINUTE_IN_MS; type Props = Omit, "onClick" | "children">; export const WalletButton = (props: Props) => { const segment = useSelectedLayoutSegment(); const isBlocked = segment === VPN_BLOCKED_SEGMENT; // eslint-disable-next-line unicorn/no-null return isBlocked ? null : ; }; const WalletButtonImpl = (props: Props) => { const api = useApi(); switch (api.type) { case ApiStateType.WalletDisconnecting: case ApiStateType.WalletConnecting: { return ( Loading... ); } case ApiStateType.NotLoaded: case ApiStateType.NoWallet: { return ; } case ApiStateType.ErrorLoadingStakeAccounts: case ApiStateType.Loaded: case ApiStateType.LoadedNoStakeAccount: case ApiStateType.LoadingStakeAccounts: { return ; } } }; type ConnectedButtonProps = Props & { api: | States[ApiStateType.ErrorLoadingStakeAccounts] | States[ApiStateType.Loaded] | States[ApiStateType.LoadedNoStakeAccount] | States[ApiStateType.LoadingStakeAccounts]; }; const ConnectedButton = ({ className, api, ...props }: ConnectedButtonProps) => { const modal = useWalletModal(); const showModal = useCallback(() => { modal.setVisible(true); }, [modal]); const logger = useLogger(); const wallet = useWallet(); const disconnectWallet = useCallback(() => { wallet.disconnect().catch((error: unknown) => { logger.error(error); }); }, [wallet, logger]); const { isMainnet, toggleMainnet } = useNetwork(); return ( {api.type === ApiStateType.Loaded && ( <>
Select stake account
)}
Change wallet Disconnect
); }; type StakeAccountSelectorProps = { api: States[ApiStateType.Loaded]; children: ReactElement; }; const StakeAccountSelector = ({ children, api }: StakeAccountSelectorProps) => { const data = useData(api.dashboardDataCacheKey, api.loadData, { refreshInterval: REFRESH_INTERVAL, }); const accounts = useMemo(() => { if (data.type === DataStateType.Loaded) { const main = api.allAccounts.find((account) => data.data.integrityStakingPublishers.some((publisher) => publisher.stakeAccount?.equals(account), ), ); const other = api.allAccounts .filter((account) => account !== main) .map((account) => ({ account, id: account.toBase58(), })); return { main, other }; } else { return; } }, [data, api]); return accounts === undefined || // eslint-disable-next-line unicorn/no-null (accounts.main === undefined && accounts.other.length === 1) ? null : ( <>
{children} {accounts.main === undefined ? ( ({ account }) => ) : ( <>
Main Account
{accounts.other.length > 0 && ( <>
Other Accounts
{({ account }) => ( )}
)} )}
); }; type AccountMenuItemProps = { api: States[ApiStateType.Loaded]; account: PublicKey; }; const AccountMenuItem = ({ account, api }: AccountMenuItemProps) => ( { api.selectAccount(account); }} className={clsx({ "pr-8 font-semibold": account === api.account, })} isDisabled={account === api.account} > {account} ); const ButtonContent = () => { const wallet = useWallet(); const primaryDomain = usePrimaryDomain(); if (primaryDomain) { return primaryDomain; } else if (wallet.publicKey) { return {wallet.publicKey}; } else if (wallet.connecting) { return "Connecting..."; } else { return "Connect"; } }; const DisconnectedButton = (props: Props) => { const modal = useWalletModal(); const showModal = useCallback(() => { modal.setVisible(true); }, [modal]); return ( Connect wallet ); }; type ButtonComponentProps = Omit, "children"> & { children: ReactNode | ReactNode[]; }; const ButtonComponent = ({ className, children, ...props }: ButtonComponentProps) => ( );