UNPKG

@reservoir0x/relay-kit-ui

Version:

Relay is the Fastest and Cheapest Way to Bridge and Transact Across Chains.

195 lines 8.49 kB
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime"; import { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { useRelayClient, useENSResolver, useIsPassthrough, useSupportedMoonPayCurrencyCode, useFallbackState } from '../../../../hooks/index.js'; import { zeroAddress } from 'viem'; import {} from '@reservoir0x/relay-sdk'; import { ProviderOptionsContext } from '../../../../providers/RelayKitProvider.js'; import { findSupportedWallet, isValidAddress } from '../../../../utils/address.js'; import useWalletAddress from '../../../../hooks/useWalletAddress.js'; import { useTokenPrice } from '@reservoir0x/relay-kit-hooks'; import { formatBN } from '../../../../utils/numbers.js'; import { UnsupportedDepositAddressChainIds } from '../../../../constants/depositAddresses.js'; const OnrampWidgetRenderer = ({ defaultWalletAddress, linkedWallets, supportedWalletVMs, multiWalletSupportEnabled, moonPayApiKey, token: _token, setToken: _setToken, children }) => { const client = useRelayClient(); const providerOptionsContext = useContext(ProviderOptionsContext); const connectorKeyOverrides = providerOptionsContext.vmConnectorKeyOverrides; const [token, setToken] = useFallbackState(_token && _setToken ? _token : { address: zeroAddress, chainId: 8453, name: 'ETH', symbol: 'ETH', decimals: 18, logoURI: 'https://assets.relay.link/icons/currencies/eth.png' }, _token && _setToken ? [_token, _setToken] : undefined); useEffect(() => { if (_token && _setToken && UnsupportedDepositAddressChainIds.includes(token.chainId)) { setToken({ address: zeroAddress, chainId: 8453, name: 'ETH', symbol: 'ETH', decimals: 18, logoURI: 'https://assets.relay.link/icons/currencies/eth.png' }); } }, [_token]); const [displayCurrency, setDisplayCurrency] = useState(false); const { data: usdTokenPriceResponse } = useTokenPrice(client?.baseApiUrl, { address: token.address, chainId: token.chainId, referrer: client?.source }, { refetchInterval: 60000 * 5, //5 minutes refetchOnWindowFocus: false }); const usdRate = usdTokenPriceResponse?.price ?? 0; const minAmountCurrency = formatBN(20 / usdRate, 5, token.decimals, false); const toChain = useMemo(() => client?.chains.find((chain) => chain.id === token.chainId), [token, client?.chains]); const toChainWalletVMSupported = !toChain?.vmType || supportedWalletVMs.includes(toChain?.vmType); const moonPayCurrency = useSupportedMoonPayCurrencyCode([ 'usdc_base', 'usdc_polygon', 'usdc', 'eth', 'eth_arbitrum', 'eth_optimism' ], moonPayApiKey, token); const fromToken = { chainId: +moonPayCurrency.chainId, address: moonPayCurrency.contractAddress, symbol: moonPayCurrency.code.includes('eth') ? 'ETH' : 'USDC', name: moonPayCurrency.code.includes('eth') ? 'ETH' : 'USDC', logoURI: moonPayCurrency.code.includes('eth') ? 'https://assets.relay.link/icons/1/light.png' : 'https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694', decimals: moonPayCurrency.code.includes('eth') ? 18 : 6 }; const fromChain = useMemo(() => client?.chains.find((chain) => chain.id === +moonPayCurrency.chainId), [fromToken, client?.chains, moonPayCurrency]); const [amount, setAmount] = useState('20'); const [amountToToken, setAmountToToken] = useState(''); const [recipient, setRecipient] = useState(defaultWalletAddress); const { displayName: toDisplayName } = useENSResolver(recipient, { refetchOnWindowFocus: false, enabled: toChain?.vmType === 'evm' }); const [fiatCurrency, setFiatCurrency] = useState({ name: 'US Dollar', code: 'usd', minAmount: 20, icon: 'https://static.moonpay.com/widget/currencies/usd.svg' }); const address = useWalletAddress(undefined, linkedWallets); const defaultRecipient = useMemo(() => { const _linkedWallet = linkedWallets?.find((linkedWallet) => address === (linkedWallet.vmType === 'evm' ? linkedWallet.address.toLowerCase() : linkedWallet.address)); const _isValidRecipient = isValidAddress(toChain?.vmType, recipient ?? '', toChain?.id, _linkedWallet?.address === recipient ? _linkedWallet?.connector : undefined, connectorKeyOverrides); if (multiWalletSupportEnabled && toChain && linkedWallets && !_isValidRecipient) { const supportedAddress = findSupportedWallet(toChain, recipient, linkedWallets, connectorKeyOverrides); return supportedAddress; } }, [ multiWalletSupportEnabled, toChain, recipient, linkedWallets, setRecipient ]); const _recipient = recipient && recipient.length > 0 ? recipient : defaultRecipient; const isRecipientLinked = (_recipient ? linkedWallets?.find((wallet) => wallet.address === _recipient) || address === _recipient : undefined) !== undefined; const isValidRecipient = isValidAddress(toChain?.vmType, _recipient ?? '', toChain?.id); const { isPassthrough, moonPayCurrency: passThroughCurrency } = useIsPassthrough(token, moonPayApiKey); useEffect(() => { setInputValue(displayCurrency ? amountToToken : amount); }, [usdRate]); const amountToTokenFormatted = amountToToken ? formatBN(parseFloat(amountToToken), 5, token.decimals) : '-'; const setInputValue = useCallback((inputValue, overrideDisplayCurrency) => { const _displayCurrency = overrideDisplayCurrency !== undefined ? overrideDisplayCurrency : displayCurrency; if (_displayCurrency) { const _amountToToken = inputValue.replace(/[^0-9.]+/g, ''); setAmountToToken(_amountToToken); const _amount = _amountToToken && +_amountToToken > 0 ? +_amountToToken * usdRate : 0; setAmount(`${parseFloat(_amount.toFixed(2))}`); } else { let _amount = ''; const numericValue = inputValue .replace(/[^0-9.]/g, '') .replace(/(\..*?)(\..*)/, '$1') .replace(/(\.\d{2})\d+/, '$1'); const regex = /^[0-9]+(\.[0-9]*)?$/; if (numericValue === '.' || numericValue.includes(',')) { _amount = '0.'; } else if (regex.test(numericValue) || numericValue === '') { _amount = numericValue; } const _amountToToken = _amount && +_amount > 0 ? +_amount / usdRate : 0; setAmount(_amount); setAmountToToken(`${_amountToToken}`); } }, [usdRate, displayCurrency]); const notEnoughFiat = !amount || +amount < 20; let ctaCopy = 'Buy'; if (notEnoughFiat) { ctaCopy = 'Enter an amount'; } else if (!_recipient && toChainWalletVMSupported) { ctaCopy = `Connect Wallet`; } else if (!_recipient) { ctaCopy = `Enter ${toChain?.displayName} address`; } return (_jsx(_Fragment, { children: children({ displayCurrency, setDisplayCurrency, recipient: _recipient, setRecipient, isRecipientLinked, isValidRecipient, amount, setAmount, amountToToken, setAmountToToken, setInputValue, token, fromToken, setToken, toChain, fromChain, toDisplayName, toChainWalletVMSupported, fiatCurrency, setFiatCurrency, amountToTokenFormatted, usdRate, minAmountCurrency, notEnoughFiat, ctaCopy, isPassthrough, moonPayCurrencyCode: isPassthrough && passThroughCurrency?.code ? passThroughCurrency?.code : moonPayCurrency.code }) })); }; export default OnrampWidgetRenderer; //# sourceMappingURL=OnrampWidgetRenderer.js.map