import { useEffect , useMemo , useState } from "react" ; import styled from "styled-components" ; import { Container , Snackbar } from "@material-ui/core" ; import { toDate } from "../helpers/utils" ; import Paper from "@material-ui/core/Paper" ; import Grid from "@material-ui/core/Grid" ; import Countdown from "react-countdown" ; import Alert from "@material-ui/lab/Alert" ; import * as anchor from "@project-serum/anchor" ; import { LAMPORTS_PER_SOL , PublicKey } from "@solana/web3.js" ; import { useWallet } from "@solana/wallet-adapter-react" ; import useSplToken from "../hooks/useSplToken" ; import ReactCountdown from "./ReactCountdown" ; import { awaitTransactionSignatureConfirmation , CandyMachineAccount , CANDY_MACHINE_PROGRAM , getCandyMachineState , mintOneToken , } from "../helpers/candy-machine" ; import { AlertState } from "../helpers/utils" ; import { MintButton } from "./MintButton" ; import { PhaseHeader } from "./PhaseHeader" ; import { GatewayProvider } from "@civic/solana-gateway-react" ; const MintContainer = styled . div `` ; export interface HomeProps { candyMachineId ? : anchor . web3 . PublicKey ; connection : anchor . web3 . Connection ; startDate : number ; txTimeout : number ; rpcHost : string ; } const Home = ( props ) => { const [ yourSOLBalance , setYourSOLBalance ] = useState < number | null > ( null ) ; const rpcUrl = props . rpcHost ; const [ isMinting , setIsMinting ] = useState ( false ) ; const wallet = useWallet ( ) ; const [ candyMachine , setCandyMachine ] = useState < CandyMachineAccount > ( ) ; const [ isLoading , isSPLExists ] = useSplToken ( ) ; const anchorWallet = useMemo ( ( ) => { if ( ! wallet || ! wallet . publicKey || ! wallet . signAllTransactions || ! wallet . signTransaction ) { return ; } return { publicKey : wallet . publicKey , signAllTransactions : wallet . signAllTransactions , signTransaction : wallet . signTransaction , } as anchor . Wallet ; } , [ wallet ] ) ; const [ alertState , setAlertState ] = useState < AlertState > ( { open : false , message : "" , severity : undefined , } ) ; const onMint = async ( ) => { try { setIsMinting ( true ) ; document . getElementById ( "#identity" ) ?. click ( ) ; if ( wallet . connected && candyMachine ?. program && wallet . publicKey ) { const mintTxId = ( await mintOneToken ( candyMachine , wallet . publicKey ) ) [ 0 ] ; let status = { err : true } ; if ( mintTxId ) { status = await awaitTransactionSignatureConfirmation ( mintTxId , props . txTimeout , props . connection , "singleGossip" , true ) ; } if ( ! status ?. err ) { setAlertState ( { open : true , message : "Congratulations! Mint succeeded!" , severity : "success" , } ) ; } else { setAlertState ( { open : true , message : "Mint failed! Please try again!" , severity : "error" , } ) ; } } } catch ( error ) { console . log ( "err " , error ) ; let message = error . msg || "Minting failed! Please try again!" ; if ( ! error . msg ) { if ( ! error . message ) { message = "Transaction Timeout! Please try again." ; } else if ( error . message . indexOf ( "0x138" ) ) { } else if ( error . message . indexOf ( "0x137" ) ) { message = `SOLD OUT!` ; } else if ( error . message . indexOf ( "0x135" ) ) { message = `Insufficient funds to mint. Please fund your wallet.` ; } } else { if ( error . code === 311 ) { message = `SOLD OUT!` ; window . location . reload ( ) ; } else if ( error . code === 312 ) { message = `Minting period hasn't started yet.` ; } } setAlertState ( { open : true , message , severity : "error" , } ) ; } finally { setIsMinting ( false ) ; } } ; useEffect ( ( ) => { ( async ( ) => { if ( ! anchorWallet ) { return ; } const balance = await props . connection . getBalance ( anchorWallet . publicKey ) ; setYourSOLBalance ( balance ) ; if ( props . candyMachineId ) { try { const cndy = await getCandyMachineState ( anchorWallet , props . candyMachineId , props . connection ) ; setCandyMachine ( cndy ) ; } catch ( e ) { console . log ( "Problem getting candy machine state" ) ; console . log ( e ) ; } } else { console . log ( "No candy machine detected in configuration." ) ; } } ) ( ) ; } , [ anchorWallet , props . candyMachineId , props . connection ] ) ; const renderer = ( { days , hours , minutes , seconds , completed , } ) => { if ( completed ) { const disabled = "cursor-not-allowed font-monstmedium text-4xl w-2/3 mx-auto mt-6 h-20 rounded-lg text-white" ; const notDisabled = "font-monstmedium text-4xl w-2/3 mx-auto mt-6 h-20 rounded-lg bg-pink-500 text-white" ; return ( < div className = "flex flex-col mt-32 justify-center" > < Container maxWidth = "xs" style = { { position : "relative" } } > < Paper style = { { padding : 24 , backgroundColor : "#151A1F" , borderRadius : 6 , } } > < div className = "" > < img src = "/images/.png" className = "mb-6 border-2 rounded border-gray-700" / > < /div> < Grid container justifyContent = "center" direction = "column" > < PhaseHeader candyMachine = { candyMachine } rpcUrl = { rpcUrl } whiteList = { isSPLExists } / > < > < MintContainer > { candyMachine ?. state . isActive && candyMachine ?. state . gatekeeper && wallet . publicKey && wallet . signTransaction ? ( < GatewayProvider wallet = { { publicKey : wallet . publicKey || new PublicKey ( CANDY_MACHINE_PROGRAM ) , signTransaction : wallet . signTransaction , } } gatekeeperNetwork = { candyMachine ?. state ?. gatekeeper ?. gatekeeperNetwork } clusterUrl = { rpcUrl } options = { { autoShowModal : false } } > < MintButton candyMachine = { candyMachine } isMinting = { isMinting } onMint = { onMint } / > < /GatewayProvider>) : (<MintButton candyMachine={candyMachine} isMinting={isMinting} onMint={onMint}/ > ) } < /MintContainer> < /> { } < /Grid> < /Paper> < /Container> < /div>); } else { return ( < ReactCountdown days = { days } minutes = { minutes } hours = { hours } seconds = { seconds } / > ) ; } } ; const candyMachineGoLive = toDate ( candyMachine ?. state . goLiveDate ) ?. getTime ( ) ; return ( < div className = "bg-container" > < Container style = { { marginTop : 100 } } > { candyMachineGoLive && wallet . connected && ( < Countdown date = { isSPLExists ? 1640199600000 : candyMachineGoLive } renderer = { renderer } / > ) } { ! candyMachine && wallet . connected && ( < div className = "text-white text-center mt-36 mb-6 text-2xl" > Loading < /div>)} { ! wallet . connected && ( < div className = "text-white font-sans text-center text-4xl mt-36" > Connect Wallet < br / > To Initiate Countdown < /div>)} < Snackbar open = { alertState . open } autoHideDuration = { 6000 } onClose = { ( ) => setAlertState ( { ... alertState , open : false } ) } > < Alert onClose = { ( ) => setAlertState ( { ... alertState , open : false } ) } severity = { alertState . severity } > { alertState . message } < /Alert> < /Snackbar> < /Container> < /div>); } ; export default Home ;