import { Spinner } from '@/internal/components/Spinner'; import { useNFTLifecycleContext } from '@/nft/components/NFTLifecycleProvider'; import { useNFTContext } from '@/nft/components/NFTProvider'; import { useMintAnalytics } from '@/nft/hooks/useMintAnalytics'; import { cn, text } from '@/styles/theme'; import { Transaction, TransactionButton, type TransactionButtonProps, type LifecycleStatus as TransactionLifecycleStatus, TransactionSponsor, TransactionStatus, TransactionStatusAction, TransactionStatusLabel, } from '@/transaction'; import type { Call } from '@/transaction/types'; import { ConnectWallet } from '@/wallet'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useAccount, useChainId } from 'wagmi'; type NFTMintButtonProps = { className?: string; label?: string; } & Pick; export function NFTMintButton({ className, label = 'Mint', disabled, }: NFTMintButtonProps) { const chainId = useChainId(); const { address } = useAccount(); const { contractAddress, tokenId, network, isEligibleToMint, buildMintTransaction, isSponsored, quantity, name, } = useNFTContext(); const { updateLifecycleStatus } = useNFTLifecycleContext(); const [callData, setCallData] = useState([]); const [mintError, setMintError] = useState(null); const { setTransactionState } = useMintAnalytics(); const handleTransactionError = useCallback( (error: string) => { updateLifecycleStatus({ statusName: 'error', statusData: { error: 'Error building mint transaction', code: 'NmNBc01', // NFT module NFTMintButton component 01 error message: error, }, }); setMintError(error); }, [updateLifecycleStatus], ); const fetchTransactions = useCallback(async () => { // don't fetch transactions until data is available if (name && address && buildMintTransaction && isEligibleToMint) { try { setCallData([]); setMintError(null); setTransactionState('buildingTransaction'); const mintTransaction = await buildMintTransaction({ takerAddress: address, contractAddress, tokenId, network, quantity, }); setCallData(mintTransaction); } catch (error) { handleTransactionError(error as string); } } else { setCallData([]); } }, [ address, buildMintTransaction, contractAddress, handleTransactionError, isEligibleToMint, name, network, quantity, setTransactionState, tokenId, ]); useEffect(() => { // need to fetch calls on quantity change instead of onClick to avoid smart wallet // popups getting blocked by safari fetchTransactions(); }, [fetchTransactions]); const handleOnStatus = useCallback( (transactionStatus: TransactionLifecycleStatus) => { setTransactionState(transactionStatus.statusName); if (transactionStatus.statusName === 'transactionPending') { updateLifecycleStatus({ statusName: 'transactionPending' }); } if ( transactionStatus.statusName === 'transactionLegacyExecuted' || transactionStatus.statusName === 'success' || transactionStatus.statusName === 'error' ) { updateLifecycleStatus(transactionStatus); } }, [updateLifecycleStatus, setTransactionState], ); const transactionButtonLabel = useMemo(() => { if (isEligibleToMint === false || mintError) { return 'Minting not available'; } if (callData.length === 0) { return ; } return label; }, [callData, isEligibleToMint, label, mintError]); if (!buildMintTransaction) { return null; } if (!address) { return ; } return ( <> {!mintError && } {mintError && (
{mintError}
)} ); }