UNPKG

@coin-voyage/paykit

Version:

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

156 lines (155 loc) 5.66 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useConfig as useBigmiConfig } from "@bigmi/react"; import { Arbitrum, Base, Bitcoin, Ethereum, Solana, Sui } from "@coin-voyage/shared/chain"; import { ChainType, PayOrderMode } from "@coin-voyage/shared/types"; import { truncateAddress, truncateENSName } from "@coin-voyage/shared/utils"; import { useWallets } from "@mysten/dapp-kit"; import { useWallet } from "@solana/wallet-adapter-react"; import { useCallback, useMemo } from "react"; import { useConfig as useWagmiConfig } from "wagmi"; import { MetaMask } from "../assets/logos"; import usePayContext from "../components/contexts/pay"; import { SquircleIcon } from "../components/ui/Icon"; import { BTC_MIN_USD_AMOUNT } from "../lib/constants"; import { ROUTE } from "../types/routes"; function getOptionTitle(subject, isDeposit) { return `${isDeposit ? "Deposit from" : "Pay on"} ${subject}`; } function getDisplayName(address, ensName) { if (ensName) { return truncateENSName(ensName, 14); } if (address) { return truncateAddress(address); } return "wallet"; } function getConnectedWalletIcons(account) { if (account.connector?.icon) { return [ _jsx(SquircleIcon, { icon: account.connector.icon, alt: account.connector.name ?? "Connected Wallet" }, "connector"), ]; } return [_jsx(MetaMask, {}, "fallback-wallet")]; } function createChainOption(config, isDeposit, onClick) { return { id: config.id, title: getOptionTitle(config.subject, isDeposit), subtitle: config.subtitle, icons: config.icons, iconShape: config.iconShape, disabled: config.disabled, onClick: () => onClick(config.chainType), }; } export function useChainOptions({ account, mode, onClick, }) { const { setRoute, paymentState } = usePayContext(); const { payOrder, senderEnsName, setConnectorChainType } = paymentState; const evmConfig = useWagmiConfig(); const utxoConfig = useBigmiConfig(); const suiWallets = useWallets(); const { wallets: solanaWallets } = useWallet(); const isDeposit = mode === PayOrderMode.DEPOSIT; const isConnected = account.isConnected; const fiatAmount = payOrder?.fulfillment.amount.value_usd; const hasEvmConnectors = evmConfig.connectors.length > 0; const hasBitcoinConnectors = utxoConfig.connectors.length > 0; const hasSolanaWallets = solanaWallets.length > 0; const hasSuiWallets = suiWallets.length > 0; const isBitcoinDisabled = typeof fiatAmount === "number" && fiatAmount < BTC_MIN_USD_AMOUNT; const displayName = useMemo(() => { return getDisplayName(account.address, senderEnsName); }, [account.address, senderEnsName]); const connectedWalletIcons = useMemo(() => { return getConnectedWalletIcons(account); }, [account]); const evmIcons = useMemo(() => { return [_jsx(Ethereum, {}, "eth"), _jsx(Base, {}, "base"), _jsx(Arbitrum, {}, "arb")]; }, []); const solanaIcons = useMemo(() => { return [_jsx(Solana, {}, "sol")]; }, []); const suiIcons = useMemo(() => { return [_jsx(Sui, {}, "sui")]; }, []); const bitcoinIcons = useMemo(() => { return [_jsx(Bitcoin, {}, "btc")]; }, []); const handleConnectedWalletClick = useCallback(() => { setConnectorChainType(account.chainType); setRoute(ROUTE.WALLET_TOKEN_SELECT); }, [account.chainType, setConnectorChainType, setRoute]); const chainConfigs = useMemo(() => { return [ { id: "evm", chainType: ChainType.EVM, subject: "Ethereum", icons: evmIcons, available: hasEvmConnectors, subtitle: "Ethereum, Base, Arbitrum ...", iconShape: "circle", }, { id: "solana", chainType: ChainType.SOL, subject: "Solana", icons: solanaIcons, available: hasSolanaWallets, }, { id: "sui", chainType: ChainType.SUI, subject: "Sui", icons: suiIcons, available: hasSuiWallets, }, { id: "bitcoin", chainType: ChainType.UTXO, subject: "Bitcoin", icons: bitcoinIcons, available: hasBitcoinConnectors, disabled: isBitcoinDisabled, subtitle: isBitcoinDisabled ? `Minimum $${BTC_MIN_USD_AMOUNT}` : undefined, }, ]; }, [ evmIcons, solanaIcons, suiIcons, bitcoinIcons, hasEvmConnectors, hasSolanaWallets, hasSuiWallets, hasBitcoinConnectors, isBitcoinDisabled, ]); const options = useMemo(() => { const result = []; if (isConnected) { result.push({ id: "connectedWallet", title: `Pay with ${displayName}`, icons: connectedWalletIcons, onClick: handleConnectedWalletClick, }); } chainConfigs .filter((config) => config.available) .forEach((config) => { result.push(createChainOption(config, isDeposit, onClick)); }); return result; }, [ isConnected, displayName, connectedWalletIcons, handleConnectedWalletClick, chainConfigs, isDeposit, onClick, ]); return { options }; }