2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  Router  from  "next/router" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  {  useCallback ,  useMemo ,  useState  }  from  "react" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  React  from  "react" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  Web3  from  "web3" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  {  AbiItem  }  from  "web3-utils" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 23:36:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  showToast  from  "@calcom/lib/notification" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  {  Button  }  from  "@calcom/ui/Button" ;  
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 23:36:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  {  useLocale  }  from  "@lib/hooks/useLocale" ;  
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  {  useContracts  }  from  "../../../contexts/contractsContext" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  genericAbi  from  "../../../web3/abis/abiWithGetBalance.json" ;  
						 
					
						
							
								
									
										
										
										
											2022-02-02 11:07:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  verifyAccount ,  {  AUTH_MESSAGE  }  from  "../../../web3/utils/verifyAccount" ;  
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								interface  Window  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ethereum : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  web3 : Web3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								interface  EvtsToVerify  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [ eventId : string ] :  boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								declare  const  window :  Window ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								interface  CryptoSectionProps  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  id : number  |  string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pathname : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  smartContractAddress : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /** When set to true, there will be only 1 button which will both connect Metamask and verify the user's wallet. Otherwise, it will be in 2 steps with 2 buttons. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  oneStep : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  verified : boolean  |  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  setEvtsToVerify : React.Dispatch < React.SetStateAction < Record < number  |  string ,  boolean > >> ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  CryptoSection  =  ( props : CryptoSectionProps )  = >  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // Crypto section which should be shown on booking page if event type requires a smart contract token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  [ ethEnabled ,  toggleEthEnabled ]  =  useState < boolean > ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  {  addContract  }  =  useContracts ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  {  t  }  =  useLocale ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  connectMetamask  =  useCallback ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( window . ethereum )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      await  window . ethereum . request ( {  method :  "eth_requestAccounts"  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      window . web3  =  new  Web3 ( window . ethereum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      toggleEthEnabled ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      toggleEthEnabled ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  verifyWallet  =  useCallback ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! window . web3 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 20:08:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  Error ( "MetaMask browser extension is not installed" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  contract  =  new  window . web3 . eth . Contract ( genericAbi  as  AbiItem [ ] ,  props . smartContractAddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  balance  =  await  contract . methods . balanceOf ( window . ethereum . selectedAddress ) . call ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  hasToken  =  balance  >  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! hasToken )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( "Specified wallet does not own any tokens belonging to this smart contract" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 20:08:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  account  =  ( await  window . web3 . eth . getAccounts ( ) ) [ 0 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 20:08:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // @ts-ignore
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        const  signature  =  await  window . web3 . eth . personal . sign ( AUTH_MESSAGE ,  account ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-03 20:08:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // @ts-ignore
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        addContract ( {  address : props.smartContractAddress ,  signature  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        await  verifyAccount ( signature ,  account ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        props . setEvtsToVerify ( ( prevState : EvtsToVerify )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          const  changedEvt  =  {  [ props . id ] :  hasToken  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return  {  . . . prevState ,  . . . changedEvt  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  catch  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      err  instanceof  Error  ?  showToast ( err . message ,  "error" )  :  showToast ( "An error has occurred" ,  "error" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ props ,  addContract ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // @TODO: Show error on either of buttons if fails. Yup schema already contains the error message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  successButton  =  useMemo ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( props . verified )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Router . push ( props . pathname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  < div  / > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ props . verified ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  verifyButton  =  useMemo ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      < Button  color = "secondary"  onClick = { verifyWallet }  type = "button"  id = "hasToken"  name = "hasToken" > 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 22:00:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        < img  className = "mr-1 h-5"  src = "/apps/metamask.svg"  / > 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        { t ( "verify_wallet" ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      < / Button > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ verifyWallet ,  t ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  connectButton  =  useMemo ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      < Button  color = "secondary"  onClick = { connectMetamask }  type = "button" > 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 22:00:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        < img  className = "mr-1 h-5"  src = "/apps/metamask.svg"  / > 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        { t ( "connect_metamask" ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      < / Button > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ connectMetamask ,  t ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  oneStepButton  =  useMemo ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      < Button 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        color = "secondary" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        type = "button" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        onClick = { async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          await  connectMetamask ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          await  verifyWallet ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } } > 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 22:00:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        < img  className = "mr-1 h-5"  src = "/apps/metamask.svg"  / > 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        { t ( "verify_wallet" ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      < / Button > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ connectMetamask ,  verifyWallet ,  t ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  determineButton  =  useCallback ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Did it in an extra function for some added readability, but this can be done in a ternary depending on preference
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( props . oneStep )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  props . verified  ?  successButton  : oneStepButton ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ethEnabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  props . verified  ?  successButton  : verifyButton ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  connectButton ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ,  [ props . verified ,  successButton ,  oneStepButton ,  connectButton ,  ethEnabled ,  props . oneStep ,  verifyButton ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    < div 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-09 00:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      className = "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transform opacity-0 transition-opacity group-hover:opacity-100 dark:bg-gray-900" 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 21:48:40 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      id = { ` crypto- ${ props . id } ` } > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      { determineButton ( ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								export  default  CryptoSection ;