import CryptoCurrencyIcon from 'components/primitives/CryptoCurrencyIcon' import { Box, Button, Flex, FormatCrypto, FormatCurrency, Text, } from 'components/primitives' import { mainnet, polygon, optimism } from 'wagmi/chains' import { useAccount, useContractReads, erc20ABI, useBalance } from 'wagmi' import { useMemo, useState } from 'react' import { zeroAddress, formatUnits } from 'viem' import { useCoinConversion } from '@reservoir0x/reservoir-kit-ui' //CONFIGURABLE: Here you may configure currencies that you want to display in the wallet menu. Native currencies, //like ETH/MATIC etc need to be fetched in a different way. Configure them below const currencies = [ { address: zeroAddress, symbol: 'ETH', decimals: mainnet.nativeCurrency.decimals, chain: { id: mainnet.id, name: mainnet.name, }, coinGeckoId: 'ethereum', }, { address: '0xA9E8aCf069C58aEc8825542845Fd754e41a9489A', symbol: 'pepecoin', decimals: 18, chain: { id: mainnet.id, name: mainnet.name, }, coinGeckoId: 'pepecoin', }, { address: '0x44971ABF0251958492FeE97dA3e5C5adA88B9185', symbol: 'basedAI', decimals: 18, chain: { id: mainnet.id, name: mainnet.name, }, coinGeckoId: 'basedai', }, { address: '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619', symbol: 'WETH', decimals: polygon.nativeCurrency.decimals, chain: { id: polygon.id, name: polygon.name, }, coinGeckoId: 'weth', }, { address: '0x4200000000000000000000000000000000000006', symbol: 'WETH', decimals: optimism.nativeCurrency.decimals, chain: { id: optimism.id, name: optimism.name, }, coinGeckoId: 'weth', }, ] type EnhancedCurrency = (typeof currencies)[0] & { usdPrice: number balance: string | number | bigint } const nonNativeCurrencies = currencies.filter( (currency) => currency.address !== zeroAddress ) const currencySymbols = currencies.map((currency) => currency.symbol).join(',') const currencyCoingeckoIds = currencies .map((currency) => currency.coinGeckoId) .join(',') const Wallet = () => { const [viewAll, setViewAll] = useState(false) const { address } = useAccount() const { data: nonNativeBalances } = useContractReads({ contracts: nonNativeCurrencies.map((currency) => ({ abi: erc20ABI, address: currency.address as `0x${string}`, chainId: currency.chain.id, functionName: 'balanceOf', args: [address as any], })), watch: true, enabled: address ? true : false, allowFailure: false, }) //CONFIGURABLE: Configure these by just changing the chainId to fetch native balance info, in addition to changing this // also make sure you change the enhancedCurrencies function to take into account for these new balances const ethBalance = useBalance({ address, chainId: mainnet.id, }) const maticBalance = useBalance({ address, chainId: polygon.id, }) const usdConversions = useCoinConversion( 'USD', currencySymbols, currencyCoingeckoIds ) const enhancedCurrencies = useMemo(() => { const currencyToUsdConversions = usdConversions.reduce((map, data) => { map[data.symbol] = data map[(data as any).coinGeckoId] = data return map }, {} as Record) return currencies.map((currency, i) => { let balance: string | number | bigint = 0n if (currency.address === zeroAddress) { //CONFIGURABLE: Configure these to show the fetched balance results configured above in the useBalance hooks switch (currency.chain.id) { case polygon.id: { balance = maticBalance.data?.value || 0n break } case mainnet.id: { balance = ethBalance.data?.value || 0n break } } } else { const index = nonNativeCurrencies.findIndex( (nonNativeCurrency) => nonNativeCurrency.chain.id === currency.chain.id && nonNativeCurrency.symbol === currency.symbol && nonNativeCurrency.coinGeckoId === currency.coinGeckoId ) balance = nonNativeBalances && nonNativeBalances[index] && (typeof nonNativeBalances[index] === 'string' || typeof nonNativeBalances[index] === 'number' || typeof nonNativeBalances[index] === 'bigint') ? (nonNativeBalances[index] as string | number | bigint) : 0n } const conversion = currencyToUsdConversions[ currency.coinGeckoId.length > 0 ? currency.coinGeckoId : currency.symbol.toLowerCase() ] const usdPrice = Number(formatUnits(BigInt(balance), currency?.decimals || 18)) * (conversion?.price || 0) return { ...currency, usdPrice, balance, } }) as EnhancedCurrency[] //CONFIGURABLE: Configure these to regenerate whenever a native balance changes, non native balances are already handled }, [usdConversions, nonNativeBalances, ethBalance, maticBalance]) const totalUsdBalance = useMemo(() => { return enhancedCurrencies.reduce( (total, { usdPrice }) => total + usdPrice, 0 ) }, [enhancedCurrencies]) const visibleCurrencies = viewAll ? enhancedCurrencies : enhancedCurrencies.slice(0, 3) console.log('Non-Native Currencies:', nonNativeCurrencies); console.log('Fetched Balances:', nonNativeBalances); console.log('Enhanced Currencies:', enhancedCurrencies); return ( Total Balance {visibleCurrencies.map((currency, i) => { return ( {currency.symbol} {currency.chain.name} {currency.coinGeckoId} ) })} ) } export default Wallet