import { ChainInfoID, SimpleChainInfoList, TxBroadcastResult } from '@marsprotocol/wallet-connector' import { useQueryClient } from '@tanstack/react-query' import classNames from 'classnames' import { AnimatedNumber, Button, DisplayCurrency, ErrorMessage, SVG, Tooltip, TxLink, } from 'components/common' import { MARS_SYMBOL } from 'constants/appConstants' import { findByDenom } from 'functions' import { getClaimUserRewardsMsgOptions } from 'functions/messages' import { useEstimateFee } from 'hooks/queries' import { lookup, lookupSymbol } from 'libs/parse' import { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import useStore from 'store' import { State } from 'types/enums' import { QUERY_KEYS } from 'types/enums/queryKeys' import styles from './IncentivesButton.module.scss' export const IncentivesButton = () => { // --------------- // EXTERNAL HOOKS // --------------- const { t } = useTranslation() const queryClient = useQueryClient() // --------------- // STORE STATE // --------------- const client = useStore((s) => s.client) const whitelistedAssets = useStore((s) => s.whitelistedAssets) const otherAssets = useStore((s) => s.otherAssets) const userWalletAddress = useStore((s) => s.userWalletAddress) const networkConfig = useStore((s) => s.networkConfig) const unclaimedRewards = useStore((s) => s.userUnclaimedRewards) const convertToDisplayCurrency = useStore((s) => s.convertToDisplayCurrency) const marsPriceState = useStore((s) => s.marsPriceState) const incentivesContractAddress = useStore((s) => s.networkConfig.contracts.incentives) const chainInfo = useStore((s) => s.chainInfo) const executeMsg = useStore((s) => s.executeMsg) // --------------- // LOCAL STATE // --------------- const [showDetails, setShowDetails] = useState(false) const [disabled, setDisabled] = useState(true) const [fetching, setFetching] = useState(false) const [submitted, setSubmitted] = useState(false) const [response, setResponse] = useState() const [error, setError] = useState() const [hasUnclaimedRewards, setHasUnclaimedRewards] = useState(false) const [unclaimedRewardsValue, setUnclaimedRewardsValue] = useState(0) // --------------- // LOCAL VARIABLES // --------------- const explorerUrl = chainInfo && SimpleChainInfoList[chainInfo.chainId as ChainInfoID].explorer const assets = [...whitelistedAssets, ...otherAssets] // --------------- // FUNCTIONS // --------------- const onClickAway = useCallback(() => { setShowDetails(false) setResponse(undefined) setError(undefined) }, []) useEffect(() => { let rewardsValue = 0 let rewardsAmount = 0 if (marsPriceState !== State.READY) return unclaimedRewards.forEach((reward) => { rewardsValue += convertToDisplayCurrency(reward) rewardsAmount += Number(reward.amount) }) setUnclaimedRewardsValue(rewardsValue) setHasUnclaimedRewards(rewardsAmount > 0) }, [unclaimedRewards, convertToDisplayCurrency, marsPriceState]) const txMsgOptions = useMemo(() => { if (!hasUnclaimedRewards) return return getClaimUserRewardsMsgOptions() }, [hasUnclaimedRewards]) const { data: fee, error: feeError } = useEstimateFee({ msg: txMsgOptions?.msg, funds: [], contract: incentivesContractAddress, }) if (feeError && error !== feeError && !fee) { setError(feeError as string) } useEffect(() => { const isFetching = submitted || (!fee && !response && hasUnclaimedRewards) if (fetching === isFetching) return setFetching(isFetching) }, [submitted, fetching, fee, response, hasUnclaimedRewards]) useEffect(() => { if (error) { setDisabled(!hasUnclaimedRewards) setSubmitted(false) return } if (response?.hash) { setDisabled(true) setSubmitted(false) return } setDisabled(!hasUnclaimedRewards) }, [error, response, hasUnclaimedRewards]) const claimRewards = async () => { if (!incentivesContractAddress || !client) { setError(t('error.errorClaim')) setDisabled(true) setSubmitted(false) return } setDisabled(true) setSubmitted(true) setError(undefined) if (!fee || !txMsgOptions) { return } try { const res = await executeMsg({ msg: txMsgOptions.msg, funds: [], contract: incentivesContractAddress, fee, }) setResponse(res) queryClient.invalidateQueries([QUERY_KEYS.REDBANK]) } catch (error) { const e = error as { message: string } setError(e.message as string) } } const transactionHash = response?.hash || '' if (!userWalletAddress) return null return (
{showDetails && ( <>

{t('incentives.marsRewardsCenter')}

{response ? (

{t('incentives.successfullyClaimed')}

) : ( <> {unclaimedRewards.map((rewards, index) => { const asset = findByDenom(assets, rewards.denom) if (!asset) return null return (

{lookupSymbol(asset.denom, assets)}

{t('redbank.redBankRewards')}

) })} )}
)}
) }