@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
JavaScript
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 };
}