UNPKG

@daimo/pay

Version:

Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.

203 lines (200 loc) 8.81 kB
import { jsx } from 'react/jsx-runtime'; import { assertNotNull } from '@daimo/pay-common'; import { useWallet as useWallet$1 } from '@solana/wallet-adapter-react'; import Logos, { SquircleIcon } from '../assets/logos.js'; import { MobileWithLogos } from '../assets/MobileWithLogos.js'; import { useConnectors } from '../hooks/useConnectors.js'; import { usePayContext } from '../hooks/usePayContext.js'; import { isCoinbaseWalletConnector, isInjectedConnector } from '../utils/index.js'; import { walletConfigs } from './walletConfigs.js'; /** Special wallet ID for "other wallets" option. */ const WALLET_ID_OTHER_WALLET = "otherWallet"; /** Special wallet ID for "mobile wallets" option. */ const WALLET_ID_MOBILE_WALLETS = "mobileWallets"; const useWallet = (id) => { const wallets = useWallets(); const wallet = wallets.find((c) => c.id === id); if (!wallet) return null; return wallet; }; const useWallets = (isMobile) => { const connectors = useConnectors(); const context = usePayContext(); const { showSolanaPaymentMethod } = context.paymentState; const { disableMobileInjector } = context; // Solana wallets available in the session (desktop & mobile) const solanaWallet = useWallet$1(); if (isMobile) { const mobileWallets = []; // Add injected wallet (if any) first, unless disabled if (!disableMobileInjector) { connectors.forEach((connector) => { if (isCoinbaseWalletConnector(connector.id)) return; if (!isInjectedConnector(connector.type)) return; // Skip any connectors that mention WalletConnect if (connector.name?.toLowerCase().includes("walletconnect")) return; mobileWallets.push({ id: connector.id, connector, shortName: connector.name, iconConnector: jsx("img", { src: connector.icon, alt: connector.name }), iconShape: "squircle", }); }); } function addIfNotPresent(idList) { if (mobileWallets.find((w) => idList.includes(w.id))) return; if (mobileWallets.length >= 3) return; const wallet = assertNotNull(walletConfigs[idList], () => `missing ${idList}`); mobileWallets.push({ id: idList, ...wallet, }); } addIfNotPresent("metaMask, metaMask-io, io.metamask, io.metamask.mobile, metaMaskSDK"); addIfNotPresent("com.trustwallet.app"); // Add other wallet mobileWallets.push({ id: WALLET_ID_OTHER_WALLET, name: "Other Wallets", shortName: "Other", iconConnector: jsx(Logos.OtherWallets, {}), iconShape: "square", showInMobileConnectors: false, }); return mobileWallets; } const wallets = connectors .filter((connector) => { // Skip any connectors that mention WalletConnect return !connector.name?.toLowerCase().includes("walletconnect"); }) .map((connector) => { // First, attempt to find a config by matching connector.id (existing logic). let walletConfigKey = Object.keys(walletConfigs).find((id) => id .split(",") .map((i) => i.trim()) .includes(connector.id)); // If not found by id, attempt a fuzzy match on connector.name. if (!walletConfigKey && connector.name) { walletConfigKey = Object.keys(walletConfigs).find((key) => { const cfgName = walletConfigs[key].name?.toLowerCase(); const connName = connector.name.toLowerCase(); return (cfgName && (cfgName.includes(connName) || connName.includes(cfgName))); }); } const c = { id: connector.id, name: connector.name ?? connector.id ?? connector.type, icon: (jsx("img", { src: connector.icon, alt: connector.name, width: "100%", height: "100%" })), connector, iconShape: connector.id === "io.rabby" ? "circle" : "squircle", isInstalled: connector.type === "mock" || (connector.type === "injected" && connector.id !== "metaMask") || connector.type === "farcasterFrame" || isCoinbaseWalletConnector(connector.id), }; if (walletConfigKey) { const wallet = walletConfigs[walletConfigKey]; return { ...c, iconConnector: connector.icon ? (jsx("img", { src: connector.icon, alt: connector.name, width: "100%", height: "100%" })) : undefined, ...wallet, }; } return c; }); wallets.push({ id: WALLET_ID_MOBILE_WALLETS, name: "Mobile Wallets", shortName: "Mobile", icon: (jsx("div", { style: { width: "100%", height: "100%", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center", transform: "scale(1.2)", transformOrigin: "center center", }, children: jsx(MobileWithLogos, {}) })), iconConnector: (jsx("div", { style: { width: "100%", height: "100%", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center", transform: "scale(1.2)", transformOrigin: "center center", }, children: jsx(MobileWithLogos, {}) })), }); if (showSolanaPaymentMethod) { const solanaAdapters = solanaWallet.wallets ?? []; // Merge by fuzzy name matching (includes comparison) wallets.forEach((w) => { // Skip wallets without a usable name to avoid matching everything if (!w.name) return; const evm = w.name.toLowerCase(); const match = solanaAdapters.find((sw) => { const sol = sw.adapter.name.toLowerCase(); return evm.includes(sol) || sol.includes(evm); }); if (match) { w.solanaConnectorName = match.adapter.name; } }); const unmatched = solanaAdapters.filter((sw) => !wallets.find((w) => w.solanaConnectorName === sw.adapter.name)); unmatched.forEach((sw) => { wallets.push({ id: `solana-${sw.adapter.name}`, name: sw.adapter.name, shortName: sw.adapter.name, icon: jsx(SquircleIcon, { icon: sw.adapter.icon, alt: sw.adapter.name }), iconConnector: (jsx(SquircleIcon, { icon: sw.adapter.icon, alt: sw.adapter.name })), iconShape: "squircle", solanaConnectorName: sw.adapter.name, }); }); } return (wallets // remove duplicate ids .filter((wallet, index, self) => self.findIndex((w) => w.id === wallet.id) === index) // remove wallet with id coinbaseWalletSDK if wallet with id 'com.coinbase.wallet' exists .filter((wallet, index, self) => !(wallet.id === "coinbaseWalletSDK" && self.find((w) => w.id === "com.coinbase.wallet"))) // remove wallet with id io.metamask if wallet with id 'metaMask' exists .filter((wallet, index, self) => !((wallet.id === "metaMaskSDK" || wallet.id === "metaMask") && self.find((w) => w.id === "io.metamask" || w.id === "io.metamask.mobile"))) // remove wallet with id 'com.warpcast.mobile' if wallet with id 'farcaster' exists .filter((wallet, index, self) => !(wallet.id === "com.warpcast.mobile" && self.find((w) => w.id === "farcaster"))) // order by isInstalled injected connectors first .sort((a, b) => { const AisInstalled = a.isInstalled && isInjectedConnector(a.connector?.type); const BisInstalled = b.isInstalled && isInjectedConnector(b.connector?.type); if (AisInstalled && !BisInstalled) return -1; if (!AisInstalled && BisInstalled) return 1; return 0; }) // order "mobile wallets" option last .sort((a, b) => { if (a.id === WALLET_ID_MOBILE_WALLETS) return 1; if (b.id === WALLET_ID_MOBILE_WALLETS) return -1; return 0; })); }; export { WALLET_ID_MOBILE_WALLETS, WALLET_ID_OTHER_WALLET, useWallet, useWallets }; //# sourceMappingURL=useWallets.js.map