Skip to content

Commit

Permalink
🥈🩸 -> Minting characters sorted (slightly), displaying them with Sele…
Browse files Browse the repository at this point in the history
…ctCharacter component for #15 #16
  • Loading branch information
Gizmotronn committed Feb 16, 2022
1 parent 40a57f3 commit 9039bad
Show file tree
Hide file tree
Showing 6 changed files with 818 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ chain = ganache
moralisSubdomain = xxxxxxx.usemoralis.com
abiPath = "F:\ethereum-boilerplate\Truffle\build\contracts\Contract.json"

alchemy_api_url: https://eth-rinkeby.alchemyapi.io/v2/gQUHfEyfP_v73J37inUmWzPnYN0nOLr_
rinkeby_key: a7a2f59191ce8477761f043f9da63a40ced24f803fd6a423930585e981ef5554
ALCHEMY: https://eth-rinkeby.alchemyapi.io/v2/gQUHfEyfP_v73J37inUmWzPnYN0nOLr_
PRIVATE: a7a2f59191ce8477761f043f9da63a40ced24f803fd6a423930585e981ef5554
58 changes: 55 additions & 3 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import React, { useEffect, useState } from 'react';
import twitterLogo from './assets/twitter-logo.svg';
import './App.css';

// Smart contract component imports
import SelectCharacter from './Components/SelectCharacter';
import { CONTRACT_ADDRESS, transformCharacterData } from './constants';
import GameContent from './utils/GameContent.json';
// Eth -> JS imports
import { ethers } from 'ethers';

// Constants
const TWITTER_HANDLE = 'TheMrScrooby';
const TWITTER_LINK = `https://twitter.com/${TWITTER_HANDLE}`;

const [currentAccount, setCurrentAccount] = useState(null);
const [characterNFT, setCharacterNFT] = useState(null);

/*
const App = () => {
const checkIfWalletIsConnected = () => {
Expand Down Expand Up @@ -62,11 +64,22 @@ const App = () => {
useEffect(() => {
checkIfWalletIsConnected(); // Runs when the page loads
const checkNetwork = async () => {
try {
if (window.ethereum.networkVersion !== '4') {
alert('Please switch to the Rinkeby test network');
}
} catch(error) {
console.log(error);
}
}
}, []);*/

const App = () => {
// State
const [currentAccount, setCurrentAccount] = useState(null);
const [characterNFT, setCharacterNFT] = useState(null);

// Actions
const checkIfWalletIsConnected = async () => {
Expand Down Expand Up @@ -143,8 +156,47 @@ const App = () => {

useEffect(() => {
checkIfWalletIsConnected();

const checkNetwork = async () => {
try {
if (window.ethereum.networkVersion !== '4') {
alert('Please switch to the Rinkeby test network');
}
} catch (error) {
console.log(error);
}
}
}, []);

// Render -> if user is connected AND does not have a character NFT, show SelectCharacter component
useEffect(() => {
const fetchNFTMetadata = async () => {
console.log('Checking for Character NFT on address:', currentAccount);

const provider = new ethers.providers.Web3Provider(window.ethereum); // component that talks to the ethereum nodes
const signer = provider.getSigner();
const gameContract = new ethers.Contract( // Contract object -> creates connection to the contract
CONTRACT_ADDRESS,
GameContent.abi,
signer
);

const txn = await gameContract.checkIfUserHasNFT();
if (txn.name) {
console.log('User has character NFT');
setCharacterNFT(transformCharacterData(txn));
} else {
console.log('User does not have character NFT');
}
};

// Only run this if the user is connected
if (currentAccount) {
console.log('Checking for Character NFT on address:', currentAccount);
fetchNFTMetadata();
}
}, [currentAccount]); // Fire this useEffect only when currentAccount changes

return (
<div className="App">
<div className="container">
Expand Down
77 changes: 76 additions & 1 deletion frontend/src/Components/SelectCharacter/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,85 @@
import React, { useEffect, useState } from 'react';
import './SelectCharacter.css'
import { ethers } from 'ethers';
import { CONTRACT_ADDRESS, transformCharacterData } from '../../constants';
import GameContent from '../../utils/GameContent.json';

const SelectCharacter = ({ setCharacterNFT }) => {
const [characters, setCharacters] = useState([]);
const [gameContract, setGameContract] = useState(null);

// Display mintable characters
useEffect(() => {
const { ethereum } = window;

if (ethereum) {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const gameContract = new ethers.Contract(
CONTRACT_ADDRESS,
GameContent.abi,
signer
);

// Set the gameContract in state
setGameContract(gameContract);
} else {
console.log("Ethereum object not found");
}
}, []);

// Fetch all characters
useEffect(() => {
const getCharacters = async () => {
try {
console.log('Getting contract characters to mint');

// Call contract function to get all characters
const charactersTxn = await gameContract.getAllDefaultCharacters();
console.log('charactersTxn:', charactersTxn);

// Transform the data of all the characters
const characters = charactersTxn.map((characterData) =>
transformCharacterData(characterData)
);

// Set all mint-able characters in state
setCharacters(characters);
} catch (error) {
console.error("Something went wrong fetching characters:", error);
}
};

// Get the characters
if (gameContract) {
getCharacters();
}
}, [gameContract]);

// Render Methods
const renderCharacters = () => {
characters.map((characters, index) => (
<div className="characters-item" key={characters.name}>
<div className="name-container">
<p>{characters.name}</p>
</div>
<img src={characters.imageURI} alt={characters.name} />
<button
type="button"
className='character-mint-button'
onClick={mintCharacterNFTAction(index)}
>{`Mint ${character.name}`}</button>
</div>
));
}

return (
<div className="select-character-container">
<h2>Mint your character</h2>
<h2>Mint Your Hero. Choose wisely.</h2>
{/* Only show this when there are characters in state */}
{characters.length > 0 && (
<div className="character-grid">{renderCharacters()}</div>
)}
</div>
);
};
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const CONTRACT_ADDRESS = "0x8aD3C1b653E5543dfb72bd9c249D943968e0fA77";

const transformCharacterData = (characterData) => {
return {
name: characterData.name,
imageURI: characterData.imageURI,
hp: characterData.hp.toNumber(),
maxHp: characterData.maxHp.toNumber(),
attackDamage: characterData.attackDamage.toNumber(),
};
};

export { CONTRACT_ADDRESS, transformCharacterData };
Loading

0 comments on commit 9039bad

Please sign in to comment.