@coin-voyage/paykit
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
99 lines (98 loc) • 5.23 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { ROUTES } from "../../../types/routes";
import { ConnectorButton, ConnectorIcon, ConnectorLabel, ConnectorsContainer, RecentlyUsedTag } from "./styles";
import Alert from "../Alert";
import { ScrollArea } from "../ScrollArea";
import { useLastConnector, useUniversalConnect } from "@coin-voyage/crypto/hooks";
import { isWalletInstalled } from "@coin-voyage/crypto/lib/utils/is-wallet-installed";
import { useIsMobile } from "@coin-voyage/shared/hooks";
import { detectBrowser } from "@coin-voyage/shared/common";
import { useCallback, useMemo } from "react";
import useLocales from "../../../hooks/useLocales";
import { useWalletConnectUri } from "../../../hooks/useWalletConnectUri";
import { useWallets } from "../../../hooks/useWallets";
import { walletConfigs } from "../../../lib/config/wallet";
import { isCoinbaseWalletConnector, isMobileWalletConnector, isWalletConnectConnector } from "../../../utils";
import usePayContext from "../../contexts/pay";
const ignoreHoist = ["walletConnect", "WalletConnect", "mobileWallet"];
const browser = detectBrowser();
export default function ConnectorList() {
const { paymentState, options } = usePayContext();
const { connectorChainType } = paymentState;
const isMobile = useIsMobile();
const { uri } = useWalletConnectUri();
const installedWallets = useWallets();
const { lastConnectorId } = useLastConnector();
const walletsToDisplay = useMemo(() => {
const wallets = [...installedWallets];
const mobileWallet = walletConfigs["mobileWallet"];
if (isMobile && connectorChainType && mobileWallet.chainTypes?.includes(connectorChainType)) {
wallets.push({
id: "mobileWallet",
...mobileWallet,
isInstalled: true,
connectors: [],
});
}
if (options?.hideRecentBadge || !lastConnectorId || ignoreHoist.includes(lastConnectorId)) {
return wallets;
}
return [...wallets.filter((w) => w.id === lastConnectorId), ...wallets.filter((w) => w.id !== lastConnectorId)];
}, [installedWallets, isMobile, connectorChainType, lastConnectorId, options]);
return (_jsx(ScrollArea, { children: walletsToDisplay.length > 0 ? (_jsx(ConnectorsContainer, { "$totalResults": walletsToDisplay.length, children: walletsToDisplay.map((wallet) => (_jsx(ConnectorItem, { wallet: wallet, walletConnectURI: uri, isRecent: wallet.id === lastConnectorId }, wallet.id))) })) : (_jsx(Alert, { error: true, children: "No wallets found." })) }));
}
const ConnectorItem = ({ wallet, isRecent, walletConnectURI, }) => {
const locales = useLocales();
const isMobile = useIsMobile();
const { route, setRoute, options, paymentState } = usePayContext();
const { connect } = useUniversalConnect({
onSuccess: (_, variables) => {
if (variables?.connector) {
setRoute(ROUTES.SELECT_TOKEN);
}
},
onError: (error) => {
if (error.message && error.message.includes("User rejected")) {
return;
}
},
});
const walletConfig = walletConfigs[wallet.id];
const redirectToMoreWallets = isMobile && (isWalletConnectConnector(wallet.id) || isMobileWalletConnector(wallet.id));
const shouldConnectImmediately = (browser === "safari" || browser === "ios") && isCoinbaseWalletConnector(wallet.id);
const deeplink = useMemo(() => {
if (redirectToMoreWallets ||
shouldConnectImmediately ||
isWalletInstalled(wallet.id) ||
!isMobile ||
!walletConfig) {
return undefined;
}
return walletConfig.getWalletDeeplink?.(walletConnectURI ?? "", paymentState.connectorChainType);
}, [
redirectToMoreWallets,
shouldConnectImmediately,
wallet.id,
isMobile,
walletConfig,
walletConnectURI,
paymentState.connectorChainType,
]);
const handleClick = useCallback(() => {
if (deeplink)
return;
if (redirectToMoreWallets) {
setRoute(ROUTES.MOBILECONNECTORS);
return;
}
if (shouldConnectImmediately) {
const walletConnector = wallet.connectors.find((w) => w.chainType === paymentState.connectorChainType);
if (!walletConnector)
return;
connect({ walletConnector });
}
paymentState.setSelectedWallet(wallet);
setRoute(ROUTES.CONNECT);
}, [deeplink, redirectToMoreWallets, shouldConnectImmediately, wallet, paymentState, setRoute, connect]);
return (_jsxs(ConnectorButton, { type: "button", as: deeplink ? "a" : undefined, href: deeplink, disabled: route !== ROUTES.CONNECTORS, onClick: handleClick, children: [_jsx(ConnectorIcon, { "data-small": wallet.iconShouldShrink, "data-shape": wallet.iconShape, children: wallet.iconConnector ?? wallet.icon }), _jsxs(ConnectorLabel, { children: [isMobile ? (wallet.shortName ?? wallet.name) : wallet.name, !options?.hideRecentBadge && isRecent && _jsx(RecentlyUsedTag, { children: locales.recent })] })] }));
};