diff --git a/README.md b/README.md index 761c669..27a744d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ Demo NFT collection for learning purposes. +Deployed on [link](https://keen-swan-c84e28.netlify.app/) + +[![nft](https://lh3.googleusercontent.com/qaMvdevQbrgmjsaGLWdvciVOgTM1GNovIQ6XPWHF8BiOPEvS4mk1Q2gACR6H4Oyv7NiBc43gDs8kiL4qI7Ejp6D48MqZ2cUrN1QekA=w600)](https://opensea.io/assets/matic/0x3cd266509d127d0eac42f4474f57d0526804b44e/16596) + ## OpenSea Testnet 1. https://testnets.opensea.io/collection/squarenft-cd2xk3yh7v diff --git a/client/public/index.html b/client/public/index.html index ba0811d..f2674a7 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -1,17 +1,17 @@ - - - - - - - - + + + + + + + + React App - - - -
- + + + +
+ diff --git a/client/src/App.css b/client/src/App.css index b65c52b..1da6de2 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -92,7 +92,7 @@ /* KeyFrames */ @-webkit-keyframes gradient-animation { 0% { - background-position: 0% 50%; + background-position: 0 50%; } 50% { @@ -100,13 +100,13 @@ } 100% { - background-position: 0% 50%; + background-position: 0 50%; } } @-moz-keyframes gradient-animation { 0% { - background-position: 0% 50%; + background-position: 0 50%; } 50% { @@ -114,13 +114,13 @@ } 100% { - background-position: 0% 50%; + background-position: 0 50%; } } @keyframes gradient-animation { 0% { - background-position: 0% 50%; + background-position: 0 50%; } 50% { @@ -128,6 +128,6 @@ } 100% { - background-position: 0% 50%; + background-position: 0 50%; } } \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index c4fe28c..1ca7282 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,130 +1,131 @@ +import {LoadingOverlay} from "@mantine/core"; +import {Contract, providers} from "ethers"; +import {useEffect, useState} from "react"; import "./App.css"; -import { providers, Contract } from "ethers"; -import { useEffect, useState } from "react"; -import { withEth } from "./lib/eth"; import epicNFT from "./lib/epicNFT.json"; -import { LoadingOverlay } from "@mantine/core"; +import {withEth} from "./lib/eth"; function App() { - const [currentAccount, setCurrentAccount] = useState(""); - const [mintedNFT, setMintedNFT] = useState(0); - const [maxNFT, setMaxNFT] = useState(0); - const [loading, setLoading] = useState(false); - const [link, setLink] = useState(""); + const [currentAccount, setCurrentAccount] = useState(""); + const [mintedNFT, setMintedNFT] = useState(0); + const [maxNFT, setMaxNFT] = useState(0); + const [loading, setLoading] = useState(false); + const [link, setLink] = useState(""); - const contractAddress = process.env.REACT_APP_STAGING_CONTRACT_ADDRESS; - const contractABI = epicNFT.abi; + const contractAddress = process.env.REACT_APP_STAGING_CONTRACT_ADDRESS; + const collectionAddress = process.env.REACT_APP_COLLECTION_ADDRESS; + const contractABI = epicNFT.abi; - const checkIfWalletConnected = withEth(async (ethereum) => { - const accounts = await ethereum.request({ method: "eth_accounts" }); - if (accounts.length !== 0) { - console.log(`Found authorized account ${accounts[0]}`); - setCurrentAccount(accounts[0]); - } - }); + const checkIfWalletConnected = withEth(async (ethereum) => { + const accounts = await ethereum.request({method: "eth_accounts"}); + if (accounts.length !== 0) { + console.log(`Found authorized account ${accounts[0]}`); + setCurrentAccount(accounts[0]); + } + }); - const connectWallet = withEth(async (ethereum) => { - const accounts = await ethereum.request({ method: "eth_requestAccounts" }); - console.log(`connected to ${accounts[0]}`); - setCurrentAccount(accounts[0]); - }); + const connectWallet = withEth(async (ethereum) => { + const accounts = await ethereum.request({method: "eth_requestAccounts"}); + console.log(`connected to ${accounts[0]}`); + setCurrentAccount(accounts[0]); + }); - const mintNFT = withEth(async (ethereum) => { - const signer = new providers.Web3Provider(ethereum).getSigner(); - const contract = new Contract(contractAddress, contractABI, signer); + const mintNFT = withEth(async (ethereum) => { + const signer = new providers.Web3Provider(ethereum).getSigner(); + const contract = new Contract(contractAddress, contractABI, signer); - const txn = await contract.mint(); - setLink(""); - setLoading(true); - console.log(`Mining ${txn.hash}…`); - await txn.wait(); - setLoading(false); - console.log(`Minted. See transaction: https://rinkeby.etherscan.io/tx/${txn.hash}`); - }); + const txn = await contract.mint(); + setLink(""); + setLoading(true); + console.log(`Mining ${txn.hash}…`); + await txn.wait(); + setLoading(false); + console.log(`Minted. See transaction: https://rinkeby.etherscan.io/tx/${txn.hash}`); + }); - const getNFTCount = withEth(async (ethereum) => { - const signer = new providers.Web3Provider(ethereum).getSigner(); - const contract = new Contract(contractAddress, contractABI, signer); + const getNFTCount = withEth(async (ethereum) => { + const signer = new providers.Web3Provider(ethereum).getSigner(); + const contract = new Contract(contractAddress, contractABI, signer); - const count = await contract.nftMintedCount(); - setMintedNFT(count.toNumber()); - const max = await contract.getMaxNFTAllowed(); - setMaxNFT(max.toNumber()); - }); + const count = await contract.nftMintedCount(); + setMintedNFT(count.toNumber()); + const max = await contract.getMaxNFTAllowed(); + setMaxNFT(max.toNumber()); + }); - useEffect(() => { - checkIfWalletConnected(); - }, [checkIfWalletConnected]); + useEffect(() => { + checkIfWalletConnected(); + }, [checkIfWalletConnected]); - useEffect(() => { - getNFTCount(); - }, [getNFTCount]); + useEffect(() => { + getNFTCount(); + }, [getNFTCount]); - useEffect(() => { - let contract; - const handleNewEpicNFT = (from, tokenID) => { - console.log(from, tokenID.toNumber()); - setMintedNFT(tokenID + 1); - setLink(`https://testnets.opensea.io/assets/${contractAddress}/${tokenID.toNumber()}`); - }; + useEffect(() => { + let contract; + const handleNewEpicNFT = (from, tokenID) => { + console.log(from, tokenID.toNumber()); + setMintedNFT(tokenID + 1); + setLink(`https://testnets.opensea.io/assets/${contractAddress}/${tokenID.toNumber()}`); + }; - if (window.ethereum) { - const signer = new providers.Web3Provider(window.ethereum).getSigner(); - contract = new Contract(contractAddress, contractABI, signer); - contract.on("NewEpicNFTMinted", handleNewEpicNFT); - } - return () => { - if (contract) { - contract.off("NewEpicNFTMinted", handleNewEpicNFT); - } - }; - }, [contractABI, contractAddress]); + if (window.ethereum) { + const signer = new providers.Web3Provider(window.ethereum).getSigner(); + contract = new Contract(contractAddress, contractABI, signer); + contract.on("NewEpicNFTMinted", handleNewEpicNFT); + } + return () => { + if (contract) { + contract.off("NewEpicNFTMinted", handleNewEpicNFT); + } + }; + }, [contractABI, contractAddress]); - return ( -
-
-
-

EpicNFTs Collection

-

Each unique. Each beautiful. Discover your NFT today.

-
- - {currentAccount ? ( - - ) : ( - - )} -

- {mintedNFT} EpicNFTs on {maxNFT} already minted -

- {link && ( -

- Hey there! We've minted your NFT. It may be blank right now.
- It can take a max of 10 min to show up on OpenSea. Here's the{" "} - - link - -

- )} - -
+ return ( +
+
+
+

EpicNFTs Collection

+

Each unique. Each beautiful. Discover your NFT today.

+
+ + {currentAccount ? ( + + ) : ( + + )} +

+ {mintedNFT} EpicNFTs on {maxNFT} already minted +

+ {link && ( +

+ Hey there! We've minted your NFT. It may be blank right now.
+ It can take a max of 10 min to show up on OpenSea. Here's the{" "} + + link + +

+ )} + +
+
+
-
-
- ); + ); } export default App; diff --git a/client/src/App.test.js b/client/src/App.test.js index 1f03afe..ba45315 100644 --- a/client/src/App.test.js +++ b/client/src/App.test.js @@ -1,8 +1,8 @@ -import { render, screen } from '@testing-library/react'; +import {render, screen} from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); }); diff --git a/client/src/index.css b/client/src/index.css index a83ad4c..1fa6859 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -6,13 +6,13 @@ html { body { padding: 0; font-family: -apple-system, Inter, BlinkMacSystemFont, 'Segoe UI', 'Roboto', - 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; + 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + monospace; } \ No newline at end of file diff --git a/client/src/index.js b/client/src/index.js index 37074f2..fc659bc 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,14 +1,14 @@ import React from "react"; import ReactDOM from "react-dom"; -import reportWebVitals from "./reportWebVitals"; import App from "./App"; import "./index.css"; +import reportWebVitals from "./reportWebVitals"; ReactDOM.render( - - - , - document.getElementById("root") + + + , + document.getElementById("root") ); reportWebVitals(); diff --git a/client/src/lib/eth.js b/client/src/lib/eth.js index 630e391..a3f0dd7 100644 --- a/client/src/lib/eth.js +++ b/client/src/lib/eth.js @@ -1,16 +1,16 @@ const getEth = () => { - const { ethereum } = window; - if (!ethereum) { - alert("Wallet not detected. Make sure you have Metamask extension installed and activated."); - } - return ethereum; + const {ethereum} = window; + if (!ethereum) { + alert("Wallet not detected. Make sure you have Metamask extension installed and activated."); + } + return ethereum; }; export const withEth = (f) => async (props) => { - try { - const ethereum = getEth(); - await f(ethereum, props); - } catch (error) { - console.error(error); - } + try { + const ethereum = getEth(); + await f(ethereum, props); + } catch (error) { + console.error(error); + } }; diff --git a/client/src/reportWebVitals.js b/client/src/reportWebVitals.js index 5253d3a..14ba227 100644 --- a/client/src/reportWebVitals.js +++ b/client/src/reportWebVitals.js @@ -1,13 +1,13 @@ const reportWebVitals = onPerfEntry => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({getCLS, getFID, getFCP, getLCP, getTTFB}) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } }; export default reportWebVitals; diff --git a/client/src/setupTests.js b/client/src/setupTests.js index 8f2609b..b28b910 100644 --- a/client/src/setupTests.js +++ b/client/src/setupTests.js @@ -2,4 +2,4 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; +import '@testing-library/jest-dom'; \ No newline at end of file diff --git a/contracts/EpicNFT.sol b/contracts/EpicNFT.sol index 8b90c18..d530da5 100644 --- a/contracts/EpicNFT.sol +++ b/contracts/EpicNFT.sol @@ -11,83 +11,82 @@ contract EpicNFT is ERC721URIStorage { Counters.Counter private _tokenIds; event NewEpicNFTMinted(address sender, uint256 tokenID); - uint256 private maxTokenAllowed = 50; + + uint256 private constant MAX_NFT_ALLOWED = 50; constructor() ERC721("SquareNFT", "SQUARE") { console.log("My first NFT contract! EPIC!!!"); } - string baseSvg1 = - ""; string[] colors = [ - "red", - "green", - "blue", - "white", - "yellow", - "cyan", - "pink", - "magenta", - "silver", - "gold" + "red", + "green", + "blue", + "white", + "yellow", + "cyan", + "pink", + "magenta", + "silver", + "gold" ]; string[] levels = [ - "Epic", - "Legendary", - "Heroic", - "Cool", - "Fantastic", - "Terrible", - "Crazy", - "Wild", - "Terrifying", - "Spooky" + "Epic", + "Legendary", + "Heroic", + "Cool", + "Fantastic", + "Terrible", + "Crazy", + "Wild", + "Terrifying", + "Spooky" ]; string[] classes = [ - "Assassin", - "Cleric", - "Rogue", - "Ninja", - "Lord", - "Wizard", - "Warrior", - "Berserker", - "Necromander", - "Summoner", - "Bard", - "Lancer" + "Assassin", + "Cleric", + "Rogue", + "Ninja", + "Lord", + "Wizard", + "Warrior", + "Berserker", + "Necromander", + "Summoner", + "Bard", + "Lancer" ]; string[] jobs = [ - "Soldier", - "Healer", - "Explorer", - "Merchant", - "Developer", - "BlackSmith", - "Hitman", - "Cook", - "Hunter", - "Sailor" + "Soldier", + "Healer", + "Explorer", + "Merchant", + "Developer", + "BlackSmith", + "Hitman", + "Cook", + "Hunter", + "Sailor" ]; function nftMintedCount() public view returns (uint256) { return _tokenIds.current(); } - function getMaxNFTAllowed() public view returns(uint){ - return maxTokenAllowed; + function getMaxNFTAllowed() public pure returns (uint) { + return MAX_NFT_ALLOWED; } function mint() public { require( - _tokenIds.current() < maxTokenAllowed, + _tokenIds.current() < MAX_NFT_ALLOWED, "the maximum of EpicNFT has already been minted" ); uint256 tokenID = _tokenIds.current(); diff --git a/lib/Base64.sol b/lib/Base64.sol index 3119f21..9aca4ba 100644 --- a/lib/Base64.sol +++ b/lib/Base64.sol @@ -12,7 +12,7 @@ pragma solidity ^0.8.0; /// @author Brecht Devos library Base64 { bytes internal constant TABLE = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// @notice Encodes some bytes to the base64 representation function encode(bytes memory data) internal pure returns (string memory) { @@ -42,18 +42,18 @@ library Base64 { let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) out := shl(8, out) out := add( - out, - and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF) + out, + and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF) ) out := shl(8, out) out := add( - out, - and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF) + out, + and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF) ) out := shl(8, out) out := add( - out, - and(mload(add(tablePtr, and(input, 0x3F))), 0xFF) + out, + and(mload(add(tablePtr, and(input, 0x3F))), 0xFF) ) out := shl(224, out) diff --git a/screenshots/Screenshot 2022-04-07 at 11.50.25.png b/screenshots/Screenshot 2022-04-07 at 11.50.25.png new file mode 100644 index 0000000..31e664c Binary files /dev/null and b/screenshots/Screenshot 2022-04-07 at 11.50.25.png differ diff --git a/screenshots/Screenshot 2022-04-07 at 18.54.18.png b/screenshots/Screenshot 2022-04-07 at 18.54.18.png new file mode 100644 index 0000000..bc8490e Binary files /dev/null and b/screenshots/Screenshot 2022-04-07 at 18.54.18.png differ diff --git a/screenshots/Screenshot 2022-04-07 at 19.27.52.png b/screenshots/Screenshot 2022-04-07 at 19.27.52.png new file mode 100644 index 0000000..0746f80 Binary files /dev/null and b/screenshots/Screenshot 2022-04-07 at 19.27.52.png differ diff --git a/screenshots/Screenshot 2022-04-08 at 05.59.44.png b/screenshots/Screenshot 2022-04-08 at 05.59.44.png new file mode 100644 index 0000000..fc86c96 Binary files /dev/null and b/screenshots/Screenshot 2022-04-08 at 05.59.44.png differ diff --git a/scripts/deploy.js b/scripts/deploy.js index d944d8a..ce2ff4a 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -1,27 +1,27 @@ -const { ethers } = require("hardhat"); // this import is optional +const {ethers} = require("hardhat"); // this import is optional async function main() { - const EpicNFT = await ethers.getContractFactory("EpicNFT"); - const contract = await EpicNFT.deploy(); - await contract.deployed(); - console.log("EpicNFT deployed to:", contract.address); + const EpicNFT = await ethers.getContractFactory("EpicNFT"); + const contract = await EpicNFT.deploy(); + await contract.deployed(); + console.log("EpicNFT deployed to:", contract.address); - let txn = await contract.mint(); - await txn.wait(); - console.log("Mint NFT #1"); + let txn = await contract.mint(); + await txn.wait(); + console.log("Mint NFT #1"); - txn = await contract.mint(); - await txn.wait(); - console.log("Mint NFT #2"); + txn = await contract.mint(); + await txn.wait(); + console.log("Mint NFT #2"); } // run the script (async () => { - try { - await main(); - process.exit(0); - } catch (err) { - console.error(err); - process.exit(1); - } + try { + await main(); + process.exit(0); + } catch (err) { + console.error(err); + process.exit(1); + } })(); diff --git a/scripts/run.js b/scripts/run.js index 8e0ba93..25f0ce7 100644 --- a/scripts/run.js +++ b/scripts/run.js @@ -1,34 +1,34 @@ -const { ethers } = require("hardhat"); // this import is optional +const {ethers} = require("hardhat"); // this import is optional async function main() { - const EpicNFT = await ethers.getContractFactory("EpicNFT"); - const contract = await EpicNFT.deploy(); - await contract.deployed(); - console.log("EpicNFT deployed to:", contract.address); + const EpicNFT = await ethers.getContractFactory("EpicNFT"); + const contract = await EpicNFT.deploy(); + await contract.deployed(); + console.log("EpicNFT deployed to:", contract.address); - let count = await contract.nftMintedCount(); - console.log(count.toNumber()); + let count = await contract.nftMintedCount(); + console.log(count.toNumber()); - let txn = await contract.mint(); - await txn.wait(); + let txn = await contract.mint(); + await txn.wait(); - count = await contract.nftMintedCount(); - console.log(count.toNumber()); + count = await contract.nftMintedCount(); + console.log(count.toNumber()); - txn = await contract.mint(); - await txn.wait(); + txn = await contract.mint(); + await txn.wait(); - count = await contract.nftMintedCount(); - console.log(count.toNumber()); + count = await contract.nftMintedCount(); + console.log(count.toNumber()); } // run the script (async () => { - try { - await main(); - process.exit(0); - } catch (err) { - console.error(err); - process.exit(1); - } + try { + await main(); + process.exit(0); + } catch (err) { + console.error(err); + process.exit(1); + } })();