-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
283ba8b
commit 01c71e6
Showing
11 changed files
with
19,452 additions
and
6,654 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import NavBar from '@components/navbar/NavBar'; | ||
import Head from 'next/head'; | ||
|
||
const Layout: React.FC = ({ children }) => ( | ||
<> | ||
<Head> | ||
<link rel="icon" href="/bp-logo.svg" /> | ||
<link rel="shortcut icon" href="/bp-logo.svg" /> | ||
</Head> | ||
<NavBar /> | ||
<main> | ||
<img | ||
className="mx-auto mt-6 mb-2" | ||
src="bp-logo.svg" | ||
alt="BP Logo" | ||
width="110" | ||
/> | ||
{children} | ||
</main> | ||
</> | ||
); | ||
|
||
export default Layout; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { createContext, useState, useEffect } from 'react'; | ||
import type { BigNumberish } from '@ethersproject/bignumber'; | ||
import type { Web3 } from '@components/navbar/MetaMask'; | ||
import { formatEther } from '@ethersproject/units'; | ||
|
||
declare let window: any; | ||
|
||
export const Web3Context = createContext<any>(null); | ||
|
||
const Web3ProviderComponent: React.FC = ({ children }) => { | ||
const [newRegister, setNewRegister] = useState<boolean>(); | ||
const [ | ||
{ | ||
gameContract, | ||
nftContract, | ||
provider, | ||
account, | ||
etherBalance, | ||
tokenBalance | ||
}, | ||
setWeb3 | ||
] = useState<any>({ | ||
gameContract: '', | ||
nftContract: '', | ||
provider: '', | ||
account: '', | ||
etherBalance: '', | ||
tokenBalance: '' | ||
}); | ||
|
||
// Listens for network changes to reload the page | ||
useEffect(() => { | ||
window.ethereum.on('chainChanged', (chainId: string) => | ||
window.location.reload() | ||
); | ||
return () => | ||
window.ethereum.removeListener('chainChanged', (chainId: string) => | ||
window.location.reload() | ||
); | ||
}, []); | ||
|
||
// Listens for a change in account and updates state | ||
useEffect(() => { | ||
if (gameContract && provider) { | ||
function newAccount(accounts: Array<string>) { | ||
const signer = provider?.getSigner(accounts[0]); | ||
|
||
gameContract | ||
.balanceOf(signer._address) | ||
.then((tokenBalance: BigNumberish) => { | ||
signer?.getBalance().then((balance: BigNumberish) => | ||
setWeb3((prev: Web3) => ({ | ||
...prev, | ||
gameContract: gameContract?.connect(signer), | ||
nftContract: nftContract?.connect(signer), | ||
account: signer._address, | ||
etherBalance: Number(formatEther(balance)).toFixed(4), | ||
tokenBalance: Number(formatEther(tokenBalance)).toFixed(4) | ||
})) | ||
); | ||
}); | ||
} | ||
|
||
window.ethereum.on('accountsChanged', newAccount); | ||
return () => | ||
window.ethereum.removeListener('accountsChanged', newAccount); | ||
} | ||
}, [account]); | ||
|
||
return ( | ||
<Web3Context.Provider | ||
value={{ | ||
gameContract, | ||
nftContract, | ||
provider, | ||
account, | ||
etherBalance, | ||
tokenBalance, | ||
newRegister, | ||
setNewRegister, | ||
setWeb3 | ||
}} | ||
> | ||
{children} | ||
</Web3Context.Provider> | ||
); | ||
}; | ||
|
||
export default Web3ProviderComponent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useState } from 'react'; | ||
import { DarkModeSwitch } from 'react-toggle-dark-mode'; | ||
|
||
const DarkModeToggle = () => { | ||
const [isDarkMode, setDarkMode] = useState(false); | ||
|
||
const toggleDarkMode = (checked: boolean) => { | ||
setDarkMode(checked); | ||
isDarkMode | ||
? document.documentElement.classList.remove('dark') | ||
: document.documentElement.classList.add('dark'); | ||
}; | ||
|
||
return ( | ||
<DarkModeSwitch checked={isDarkMode} onChange={toggleDarkMode} size={35} /> | ||
); | ||
}; | ||
|
||
export default DarkModeToggle; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Loader from 'react-loader-spinner'; | ||
|
||
interface Props { | ||
isLoading: boolean; | ||
} | ||
|
||
const Loading = ({ isLoading }: Props) => | ||
isLoading ? ( | ||
<div className="flex justify-center"> | ||
<Loader type="TailSpin" color="#009900" height={100} width={100} /> | ||
</div> | ||
) : null; | ||
|
||
export default Loading; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { useContext } from 'react'; | ||
import { Web3Context } from '@components/context/Web3Context'; | ||
import { gameABI } from '@components/ABIs/gameABI'; | ||
import { nftABI } from '@components/ABIs/nftABI'; | ||
|
||
import { Web3Provider } from '@ethersproject/providers'; | ||
import { Contract } from '@ethersproject/contracts'; | ||
import { formatEther } from '@ethersproject/units'; | ||
import { toast } from 'react-toastify'; | ||
|
||
declare let window: any; | ||
|
||
export interface Web3 { | ||
gameContract: any; | ||
nftContract: Contract | string; | ||
provider: Web3Provider; | ||
account: string; | ||
etherBalance: string; | ||
tokenBalance: string; | ||
} | ||
|
||
const MetaMask = () => { | ||
const { account, setWeb3 } = useContext(Web3Context); | ||
|
||
async function enableEth() { | ||
try { | ||
if (window.ethereum) { | ||
const ethereum = window.ethereum; | ||
|
||
const provider = new Web3Provider(ethereum); | ||
const [address] = await ethereum.request({ | ||
method: 'eth_requestAccounts' | ||
}); | ||
const chainId = await ethereum.request({ method: 'eth_chainId' }); | ||
|
||
let nftAddress; | ||
let gameAddress; | ||
switch (chainId) { | ||
case '0x1': // Mainnet | ||
nftAddress = ''; | ||
gameAddress = ''; | ||
break; | ||
case '0x3': // Ropsten | ||
nftAddress = ''; | ||
gameAddress = ''; | ||
break; | ||
case '0x4': // Rinkeby | ||
nftAddress = '0x8F7117FeA39fdB8E3335090d7211A6128E4d5cC0'; | ||
gameAddress = '0x141EC0C2b4C193675594EAf316faAD8784dA8A11'; | ||
break; | ||
case '0x89': // Polygon Mainnet | ||
nftAddress = ''; | ||
gameAddress = ''; | ||
break; | ||
case '0x13881': // Polygon Testnet | ||
nftAddress = ''; | ||
gameAddress = ''; | ||
break; | ||
case '0x7a69': // Hardhat Local | ||
nftAddress = '0x5FbDB2315678afecb367f032d93F642f64180aa3'; | ||
gameAddress = '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512'; | ||
} | ||
|
||
const signer = provider.getSigner(address); | ||
|
||
const nftContract = nftAddress | ||
? new Contract(nftAddress, nftABI, signer) | ||
: ''; | ||
const gameContract: any = gameAddress | ||
? new Contract(gameAddress, gameABI, signer) | ||
: ''; | ||
|
||
const account = signer._address; | ||
|
||
const tokenBalance = Number( | ||
formatEther(await gameContract.balanceOf(account)) | ||
).toFixed(4); | ||
console.log(tokenBalance); | ||
|
||
const etherBalance = Number( | ||
formatEther(await signer.getBalance()) | ||
).toFixed(4); | ||
|
||
setWeb3((prev: Web3) => ({ | ||
...prev, | ||
gameContract, | ||
nftContract, | ||
provider, | ||
account, | ||
etherBalance, | ||
tokenBalance | ||
})); | ||
} else if (window.web3) { | ||
console.log('Update MetaMask'); | ||
} else { | ||
console.log('Enable MetaMask'); | ||
} | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
} | ||
|
||
return ( | ||
<div className="py-3"> | ||
{!account ? ( | ||
<button className="metamask-btn" onClick={enableEth}> | ||
Connect Wallet | ||
</button> | ||
) : ( | ||
<button | ||
className="blue-btn" | ||
onClick={() => | ||
toast.info(`Your wallet address is: ${account}`, { | ||
autoClose: 3000, | ||
position: 'top-center', | ||
style: { | ||
width: 520 | ||
}, | ||
theme: 'colored' | ||
}) | ||
} | ||
> | ||
Wallet Connected | ||
</button> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default MetaMask; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { useRouter } from 'next/router'; | ||
import Link from 'next/link'; | ||
import { Web3Context } from '@components/context/Web3Context'; | ||
|
||
import { ToastContainer } from 'react-toastify'; | ||
import MetaMask from './MetaMask'; | ||
import { useContext } from 'react'; | ||
import DarkModeToggle from '@components/helper/DarkModeToggle'; | ||
|
||
const NavBar = () => { | ||
const { etherBalance, tokenBalance } = useContext(Web3Context); | ||
const { asPath: path } = useRouter(); | ||
|
||
return ( | ||
<> | ||
<ToastContainer /> | ||
<header | ||
className="flex justify-around items-center py-3 | ||
border-b-2 border-gray-100 dark:border-gray-700" | ||
> | ||
<nav> | ||
<ul className="flex justify-around text-center"> | ||
<li className={path === '/' ? 'active-nav' : 'nav-item'}> | ||
<Link href="/">Home</Link> | ||
</li> | ||
<li | ||
className={path === '/predictiongame' ? 'active-nav' : 'nav-item'} | ||
> | ||
<Link href="/predictiongame">Prediction Game</Link> | ||
</li> | ||
</ul> | ||
</nav> | ||
<div className="flex items-center"> | ||
<div className="mr-10 pt-1"> | ||
<p>BP Token Balance: {tokenBalance}</p> | ||
<p className="">Ether Balance: {etherBalance}</p> | ||
</div> | ||
<MetaMask /> | ||
<div className="ml-5"> | ||
<DarkModeToggle /> | ||
</div> | ||
</div> | ||
</header> | ||
</> | ||
); | ||
}; | ||
|
||
export default NavBar; |
Oops, something went wrong.