UNPKG

@daimo/pay

Version:

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

193 lines (190 loc) 6.44 kB
import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import { getAddressContraction } from '@daimo/pay-common'; import { useWallet } from '@solana/wallet-adapter-react'; import { motion } from 'framer-motion'; import { useAccount } from 'wagmi'; import { Solana, Ethereum, Optimism, Arbitrum, Base, Polygon } from '../../../assets/chains.js'; import { USDC } from '../../../assets/coins.js'; import defaultTheme from '../../../constants/defaultTheme.js'; import { ROUTES } from '../../../constants/routes.js'; import { useDaimoPay } from '../../../hooks/useDaimoPay.js'; import useLocales from '../../../hooks/useLocales.js'; import { usePayContext } from '../../../hooks/usePayContext.js'; import styled from '../../../styles/styled/index.js'; import { formatUsd } from '../../../utils/format.js'; const OrderHeader = ({ minified = false, show = "all" }) => { const { paymentState, route } = usePayContext(); const { isConnected: isEthConnected, address, connector } = useAccount(); const { connected: isSolanaConnected, publicKey, wallet: solanaWallet } = useWallet(); const { senderEnsName } = paymentState; const { order } = useDaimoPay(); const ethWalletDisplayName = senderEnsName ?? (address ? getAddressContraction(address) : "wallet"); const solWalletDisplayName = getAddressContraction( publicKey?.toBase58() ?? "" ); const orderUsd = order?.destFinalCallTokenAmount.usd; const locales = useLocales(); const titleAmountContent = (() => { if (paymentState.isDepositFlow) { return route === ROUTES.SELECT_TOKEN ? ( // TODO: make this match `ModalH1` font size for mobile /* @__PURE__ */ jsx("span", { style: { fontSize: "19px", lineHeight: "22px" }, children: locales.yourBalances }) ) : null; } else { return orderUsd != null ? /* @__PURE__ */ jsx("span", { children: formatUsd(orderUsd, "nearest") }) : null; } })(); const renderIcon = (icon, name, size = 32) => { if (!icon) { return null; } return /* @__PURE__ */ jsx(LogoContainer, { $size: size, $zIndex: 1, style: { borderRadius: "22.5%" }, children: typeof icon === "string" ? /* @__PURE__ */ jsx( "img", { src: icon, alt: name || "wallet", style: { maxWidth: "100%", maxHeight: "100%" } } ) : icon }); }; let walletIcon = renderIcon(connector?.icon); let solanaIcon = renderIcon( solanaWallet?.adapter.icon || /* @__PURE__ */ jsx(Solana, {}), solanaWallet?.adapter.name ); if (minified) { if (titleAmountContent != null) { return /* @__PURE__ */ jsxs(MinifiedContainer, { children: [ /* @__PURE__ */ jsx(MinifiedTitleAmount, { children: titleAmountContent }), show === "evm" && isEthConnected && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(SubtitleContainer, { children: [ /* @__PURE__ */ jsx(Subtitle, { children: ethWalletDisplayName }), walletIcon ] }) }), show === "solana" && isSolanaConnected && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(SubtitleContainer, { children: [ /* @__PURE__ */ jsx(Subtitle, { children: solWalletDisplayName }), solanaIcon ] }) }) ] }); } } else { return /* @__PURE__ */ jsxs(Fragment, { children: [ titleAmountContent && /* @__PURE__ */ jsx(TitleAmount, { children: titleAmountContent }), /* @__PURE__ */ jsxs(AnyChainAnyCoinContainer, { children: [ /* @__PURE__ */ jsx(CoinLogos, {}), /* @__PURE__ */ jsx(Subtitle, { children: locales.tokensAccepted }) ] }) ] }); } }; function CoinLogos({ $size = 24 }) { const logos = [ /* @__PURE__ */ jsx(Ethereum, {}, "eth"), /* @__PURE__ */ jsx(USDC, {}, "usdc"), /* @__PURE__ */ jsx(Optimism, {}, "optimism"), /* @__PURE__ */ jsx(Arbitrum, {}, "arbitrum"), /* @__PURE__ */ jsx(Base, {}, "base"), /* @__PURE__ */ jsx(Polygon, {}, "polygon"), /* @__PURE__ */ jsx(Solana, {}, "solana") ]; const logoBlock = (element, index) => /* @__PURE__ */ jsx( LogoContainer, { $marginLeft: index !== 0 ? -($size / 3) : 0, $zIndex: logos.length - index, $size, transition: { duration: 0.5, ease: [0.175, 0.885, 0.32, 0.98] }, children: element }, index ); return /* @__PURE__ */ jsx(Logos, { children: logos.map((element, index) => logoBlock(element, index)) }); } const TitleAmount = styled(motion.h1)` margin-bottom: 24px; padding: 0; line-height: 66px; font-size: 64px; font-weight: var(--ck-modal-h1-font-weight, 600); color: ${(props) => { if (props.$error) return "var(--ck-body-color-danger)"; if (props.$valid) return "var(--ck-body-color-valid)"; return "var(--ck-body-color)"; }}; @media only screen and (max-width: ${defaultTheme.mobileWidth}px) { font-size: 64px; } display: flex; align-items: center; justify-content: center; gap: 8px; `; const Subtitle = styled(motion.div)` font-size: 18px; font-weight: 500; line-height: 21px; color: var(--ck-body-color-muted); `; const MinifiedTitleAmount = styled(motion.div)` font-size: 32px; font-weight: var(--ck-modal-h1-font-weight, 600); line-height: 36px; color: var(--ck-body-color); display: flex; align-items: center; justify-content: start; gap: 8px; `; const MinifiedContainer = styled(motion.div)` display: flex; align-items: center; justify-content: space-between; width: 100%; margin-bottom: 24px; `; const AnyChainAnyCoinContainer = styled(motion.div)` display: flex; vertical-align: middle; align-items: center; justify-content: center; text-align: center; gap: 8px; margin-bottom: 24px; `; const LogoContainer = styled(motion.div)` display: block; overflow: hidden; user-select: none; display: flex; align-items: center; justify-content: center; margin-left: ${(props) => props.$marginLeft || 0}px; z-index: ${(props) => props.$zIndex || 2}; width: ${(props) => props.$size}px; height: ${(props) => props.$size}px; border-radius: 9999px; svg { display: block; width: 100%; height: auto; } `; const Logos = styled(motion.div)` display: flex; align-items: center; justify-content: center; `; const SubtitleContainer = styled.div` display: flex; align-items: center; justify-content: flex-end; gap: 8px; `; export { OrderHeader }; //# sourceMappingURL=index.js.map