@daimo/pay
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
101 lines (98 loc) • 5.82 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { ROUTES } from '../../../constants/routes.js';
import { useConnect } from '../../../hooks/useConnect.js';
import { useDaimoPay } from '../../../hooks/useDaimoPay.js';
import useIsMobile from '../../../hooks/useIsMobile.js';
import { useLastConnector } from '../../../hooks/useLastConnector.js';
import { usePayContext } from '../../../hooks/usePayContext.js';
import { detectBrowser, isCoinbaseWalletConnector } from '../../../utils/index.js';
import { useWallets, WALLET_ID_OTHER_WALLET, WALLET_ID_MOBILE_WALLETS } from '../../../wallets/useWallets.js';
import { ScrollArea } from '../ScrollArea/index.js';
import Alert from '../Alert/index.js';
import { ConnectorsContainer, ConnectorButton, ConnectorIcon, ConnectorLabel, RecentlyUsedTag, SkeletonIcon, SkeletonLabel } from './styles.js';
const ConnectorList = () => {
const context = usePayContext();
const { isMobile } = useIsMobile();
const wallets = useWallets(isMobile);
const { lastConnectorId } = useLastConnector();
const { paymentState } = useDaimoPay();
const walletsToDisplay = context.options?.hideRecentBadge
? wallets
: [
// move last used wallet to top of list
// using .filter and spread to avoid mutating original array order with .sort
...wallets.filter((wallet) => lastConnectorId === wallet.connector?.id),
...wallets.filter((wallet) => lastConnectorId !== wallet.connector?.id),
];
// For mobile flow, we need to wait for the order to be hydrated before
// we can deeplink to the in-wallet browser.
const shouldWaitForHydration = isMobile && !context.paymentState.isDepositFlow;
const ready = !shouldWaitForHydration || paymentState === "payment_unpaid";
return (jsxs(ScrollArea, { mobileDirection: "horizontal", children: [walletsToDisplay.length === 0 && (jsx(Alert, { error: true, children: "No connectors found in ConnectKit config." })), !ready && walletsToDisplay.length > 0 && (jsx(ConnectorsContainer, { "$mobile": isMobile, "$totalResults": walletsToDisplay.length, children: walletsToDisplay.map((_, idx) => (jsx(SkeletonConnectorItem, {}, idx))) })), ready && walletsToDisplay.length > 0 && (jsx(ConnectorsContainer, { "$mobile": isMobile, "$totalResults": walletsToDisplay.length, children: walletsToDisplay.map((wallet) => (jsx(ConnectorItem, { wallet: wallet, isRecent: wallet.id === lastConnectorId }, wallet.id))) }))] }));
};
const ConnectorItem = ({ wallet, isRecent, }) => {
const { isMobile } = useIsMobile();
const context = usePayContext();
const { connect } = useConnect();
// The "Other" 2x2 connector, goes to the MobileConnectors page.
const redirectToMoreWallets = isMobile && wallet.id === WALLET_ID_OTHER_WALLET;
const redirectToMobileWallets = wallet.id === WALLET_ID_MOBILE_WALLETS;
// Safari requires opening popup on user gesture, so we connect immediately here
const shouldConnectImmediately = (detectBrowser() === "safari" || detectBrowser() === "ios") &&
isCoinbaseWalletConnector(wallet.connector?.id);
const onClick = () => {
const meta = { event: "connector-list-click", walletId: wallet.id };
// Desktop multi-chain wallet flow: prompt for chain selection.
if (wallet.solanaConnectorName && !isMobile) {
const supportsEvm = wallet.connector?.name != null;
if (supportsEvm) {
context.paymentState.setSelectedWallet(wallet);
context.setRoute(ROUTES.SELECT_WALLET_CHAIN, meta);
return;
}
else {
context.setSolanaConnector(wallet.solanaConnectorName);
context.setRoute(ROUTES.SOLANA_CONNECTOR, meta);
return;
}
}
if (redirectToMoreWallets) {
context.setRoute(ROUTES.MOBILECONNECTORS, meta);
}
else if (redirectToMobileWallets) {
if (context.paymentState.isDepositFlow) {
context.paymentState.setSelectedWallet(wallet);
context.setRoute(ROUTES.SELECT_WALLET_AMOUNT, meta);
}
else {
context.setPendingConnectorId(WALLET_ID_MOBILE_WALLETS);
context.setRoute(ROUTES.CONNECT, meta);
}
}
else if (context.paymentState.isDepositFlow &&
isMobile &&
!wallet.connector) {
context.paymentState.setSelectedWallet(wallet);
context.setRoute(ROUTES.SELECT_WALLET_AMOUNT, meta);
}
else if (isMobile &&
wallet.getDaimoPayDeeplink != null &&
!wallet.connector) {
context.paymentState.openInWalletBrowser(wallet);
}
else {
if (shouldConnectImmediately) {
connect({ connector: wallet.connector });
}
context.setPendingConnectorId(wallet.id);
context.setRoute(ROUTES.CONNECT, meta);
}
};
return (jsxs(ConnectorButton, { type: "button", onClick: onClick, 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, !context.options?.hideRecentBadge && isRecent && (jsx(RecentlyUsedTag, { children: jsx("span", { children: "Recent" }) }))] })] }));
};
const SkeletonConnectorItem = () => {
const { isMobile } = useIsMobile();
return (jsxs(ConnectorButton, { type: "button", disabled: true, children: [jsx(SkeletonIcon, { "$mobile": isMobile }), jsx(SkeletonLabel, { "$mobile": isMobile })] }));
};
export { ConnectorList as default };
//# sourceMappingURL=index.js.map