import React, { useEffect, useCallback, useMemo, useState } from "react"; import { SupportedChains, useClaim, useGetEnvChainId, useWhitelistSync, G$Amount } from "@gooddollar/web3sdk-v2"; import { Text, View } from "native-base"; import { noop, isNil } from "lodash"; import { useEthers } from "@usedapp/core"; import { useQueryParam } from "../../hooks/useQueryParam"; import { Web3ActionButton } from "../../advanced"; import { FVFlowProps } from "./types"; import { TxModal, VerifyUniqueModal } from "../web3"; const ClaimButton = ({ firstName, method, refresh, claimed, claiming, claim, chainId, handleConnect, onEvent, redirectUrl, supportedChains = [SupportedChains.CELO, SupportedChains.FUSE, SupportedChains.XDC], ...props }: FVFlowProps) => { const { account } = useEthers(); const [claimConfirming, setClaimConfirming] = useState(undefined); const [whitelistLoading, setWhitelistLoading] = useState(false); const [faceVerifying, setFaceVerifying] = useState(false); const { isWhitelisted, claimAmount } = useClaim(refresh); const isVerified = useQueryParam("verified", true); const { chainId: defaultChainId, defaultEnv } = useGetEnvChainId(); const { celoWhitelisted, syncStatus } = useWhitelistSync(); const handleClaim = useCallback(async () => { const success = await claim(); if (success !== true) { return; } }, [claim, setClaimConfirming]); const handleModalOpen = useCallback(async () => { if (isNil(isWhitelisted)) { // no value for isWhitelisted means we are not having a established connection to bc yet but should expect soon, handled by useEffect setWhitelistLoading(true); return; } if (isWhitelisted) { await handleClaim(); return; } else { // means we no longer are expecting a claimCall and actionModal should show default verify uniqueness message setClaimConfirming(false); setFaceVerifying(true); } if (celoWhitelisted && syncStatus) { const success = await syncStatus; if (!success) { return; } await handleClaim(); } }, [isWhitelisted, celoWhitelisted, syncStatus, faceVerifying, setClaimConfirming, setWhitelistLoading, handleClaim]); useEffect(() => { if (claiming?.status === "PendingSignature") { setClaimConfirming(true); return; } setClaimConfirming(false); }, [claiming]); const buttonTitle = useMemo(() => { if (!isWhitelisted || !claimAmount || (chainId && !supportedChains.includes(chainId))) { return "CLAIM NOW"; } const amount = G$Amount("G$", claimAmount, chainId ?? defaultChainId, defaultEnv); return "CLAIM NOW " + amount.format({ fixedPrecisionDigits: 2, useFixedPrecision: true, significantDigits: 2 }); }, [isWhitelisted, chainId, claimAmount, defaultChainId, defaultEnv]); // handles a delay in fetching isWhitelisted after just being connected useEffect(() => { if (whitelistLoading) { // making sure it only runs once (is set after useEffect completes) setWhitelistLoading(false); handleModalOpen().catch(noop); } }, [/* used */ isWhitelisted, whitelistLoading, setWhitelistLoading, handleModalOpen]); // trigger claim when user succesfully has verified through FV // uses the first claimer flow useEffect(() => { const doClaim = async () => { if (isVerified && account) { setClaimConfirming(true); await handleClaim(); } }; if (claimed === false && claimConfirming === undefined) doClaim().catch(noop); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isVerified, account, claimed, claimConfirming]); return ( {faceVerifying && !isWhitelisted ? ( { setFaceVerifying(false); }} chainId={chainId} firstName={firstName} method={method} /> ) : claimConfirming && (isVerified || isWhitelisted) ? ( ) : claiming?.status === "Mining" || claiming?.status === "Success" ? ( // because of small delay we need to check for both so the modal does not close pre-maturely ) : null} ); }; export default ClaimButton;