@reservoir0x/relay-kit-ui
Version:
Relay is the Fastest and Cheapest Way to Bridge and Transact Across Chains.
195 lines • 8.49 kB
JavaScript
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