format project

This commit is contained in:
Ruidy 2022-04-11 06:01:09 -04:00
parent e9aaefcd04
commit cdcba91f34
18 changed files with 263 additions and 259 deletions

View file

@ -2,6 +2,10 @@
Demo NFT collection for learning purposes. 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 ## OpenSea Testnet
1. https://testnets.opensea.io/collection/squarenft-cd2xk3yh7v 1. https://testnets.opensea.io/collection/squarenft-cd2xk3yh7v

View file

@ -1,17 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8"/>
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000"/>
<meta name="description" content="Web site created using create-react-app" /> <meta name="description" content="Web site created using create-react-app"/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
<title>React App</title> <title>React App</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
</body> </body>
</html> </html>

View file

@ -92,7 +92,7 @@
/* KeyFrames */ /* KeyFrames */
@-webkit-keyframes gradient-animation { @-webkit-keyframes gradient-animation {
0% { 0% {
background-position: 0% 50%; background-position: 0 50%;
} }
50% { 50% {
@ -100,13 +100,13 @@
} }
100% { 100% {
background-position: 0% 50%; background-position: 0 50%;
} }
} }
@-moz-keyframes gradient-animation { @-moz-keyframes gradient-animation {
0% { 0% {
background-position: 0% 50%; background-position: 0 50%;
} }
50% { 50% {
@ -114,13 +114,13 @@
} }
100% { 100% {
background-position: 0% 50%; background-position: 0 50%;
} }
} }
@keyframes gradient-animation { @keyframes gradient-animation {
0% { 0% {
background-position: 0% 50%; background-position: 0 50%;
} }
50% { 50% {
@ -128,6 +128,6 @@
} }
100% { 100% {
background-position: 0% 50%; background-position: 0 50%;
} }
} }

View file

@ -1,130 +1,131 @@
import {LoadingOverlay} from "@mantine/core";
import {Contract, providers} from "ethers";
import {useEffect, useState} from "react";
import "./App.css"; 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 epicNFT from "./lib/epicNFT.json";
import { LoadingOverlay } from "@mantine/core"; import {withEth} from "./lib/eth";
function App() { function App() {
const [currentAccount, setCurrentAccount] = useState(""); const [currentAccount, setCurrentAccount] = useState("");
const [mintedNFT, setMintedNFT] = useState(0); const [mintedNFT, setMintedNFT] = useState(0);
const [maxNFT, setMaxNFT] = useState(0); const [maxNFT, setMaxNFT] = useState(0);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [link, setLink] = useState(""); const [link, setLink] = useState("");
const contractAddress = process.env.REACT_APP_STAGING_CONTRACT_ADDRESS; const contractAddress = process.env.REACT_APP_STAGING_CONTRACT_ADDRESS;
const contractABI = epicNFT.abi; const collectionAddress = process.env.REACT_APP_COLLECTION_ADDRESS;
const contractABI = epicNFT.abi;
const checkIfWalletConnected = withEth(async (ethereum) => { const checkIfWalletConnected = withEth(async (ethereum) => {
const accounts = await ethereum.request({ method: "eth_accounts" }); const accounts = await ethereum.request({method: "eth_accounts"});
if (accounts.length !== 0) { if (accounts.length !== 0) {
console.log(`Found authorized account ${accounts[0]}`); console.log(`Found authorized account ${accounts[0]}`);
setCurrentAccount(accounts[0]); setCurrentAccount(accounts[0]);
} }
}); });
const connectWallet = withEth(async (ethereum) => { const connectWallet = withEth(async (ethereum) => {
const accounts = await ethereum.request({ method: "eth_requestAccounts" }); const accounts = await ethereum.request({method: "eth_requestAccounts"});
console.log(`connected to ${accounts[0]}`); console.log(`connected to ${accounts[0]}`);
setCurrentAccount(accounts[0]); setCurrentAccount(accounts[0]);
}); });
const mintNFT = withEth(async (ethereum) => { const mintNFT = withEth(async (ethereum) => {
const signer = new providers.Web3Provider(ethereum).getSigner(); const signer = new providers.Web3Provider(ethereum).getSigner();
const contract = new Contract(contractAddress, contractABI, signer); const contract = new Contract(contractAddress, contractABI, signer);
const txn = await contract.mint(); const txn = await contract.mint();
setLink(""); setLink("");
setLoading(true); setLoading(true);
console.log(`Mining ${txn.hash}`); console.log(`Mining ${txn.hash}`);
await txn.wait(); await txn.wait();
setLoading(false); setLoading(false);
console.log(`Minted. See transaction: https://rinkeby.etherscan.io/tx/${txn.hash}`); console.log(`Minted. See transaction: https://rinkeby.etherscan.io/tx/${txn.hash}`);
}); });
const getNFTCount = withEth(async (ethereum) => { const getNFTCount = withEth(async (ethereum) => {
const signer = new providers.Web3Provider(ethereum).getSigner(); const signer = new providers.Web3Provider(ethereum).getSigner();
const contract = new Contract(contractAddress, contractABI, signer); const contract = new Contract(contractAddress, contractABI, signer);
const count = await contract.nftMintedCount(); const count = await contract.nftMintedCount();
setMintedNFT(count.toNumber()); setMintedNFT(count.toNumber());
const max = await contract.getMaxNFTAllowed(); const max = await contract.getMaxNFTAllowed();
setMaxNFT(max.toNumber()); setMaxNFT(max.toNumber());
}); });
useEffect(() => { useEffect(() => {
checkIfWalletConnected(); checkIfWalletConnected();
}, [checkIfWalletConnected]); }, [checkIfWalletConnected]);
useEffect(() => { useEffect(() => {
getNFTCount(); getNFTCount();
}, [getNFTCount]); }, [getNFTCount]);
useEffect(() => { useEffect(() => {
let contract; let contract;
const handleNewEpicNFT = (from, tokenID) => { const handleNewEpicNFT = (from, tokenID) => {
console.log(from, tokenID.toNumber()); console.log(from, tokenID.toNumber());
setMintedNFT(tokenID + 1); setMintedNFT(tokenID + 1);
setLink(`https://testnets.opensea.io/assets/${contractAddress}/${tokenID.toNumber()}`); setLink(`https://testnets.opensea.io/assets/${contractAddress}/${tokenID.toNumber()}`);
}; };
if (window.ethereum) { if (window.ethereum) {
const signer = new providers.Web3Provider(window.ethereum).getSigner(); const signer = new providers.Web3Provider(window.ethereum).getSigner();
contract = new Contract(contractAddress, contractABI, signer); contract = new Contract(contractAddress, contractABI, signer);
contract.on("NewEpicNFTMinted", handleNewEpicNFT); contract.on("NewEpicNFTMinted", handleNewEpicNFT);
} }
return () => { return () => {
if (contract) { if (contract) {
contract.off("NewEpicNFTMinted", handleNewEpicNFT); contract.off("NewEpicNFTMinted", handleNewEpicNFT);
} }
}; };
}, [contractABI, contractAddress]); }, [contractABI, contractAddress]);
return ( return (
<div className="App"> <div className="App">
<div className="container"> <div className="container">
<div className="header-container"> <div className="header-container">
<p className="header gradient-text">EpicNFTs Collection</p> <p className="header gradient-text">EpicNFTs Collection</p>
<p className="sub-text">Each unique. Each beautiful. Discover your NFT today.</p> <p className="sub-text">Each unique. Each beautiful. Discover your NFT today.</p>
<div> <div>
<LoadingOverlay visible={loading} /> <LoadingOverlay visible={loading}/>
{currentAccount ? ( {currentAccount ? (
<button onClick={mintNFT} className="cta-button mint-button"> <button onClick={mintNFT} className="cta-button mint-button">
Mint your EpicNFT Mint your EpicNFT
</button> </button>
) : ( ) : (
<button className="cta-button connect-wallet-button" onClick={connectWallet}> <button className="cta-button connect-wallet-button" onClick={connectWallet}>
Connect with Wallet Connect with Wallet
</button> </button>
)} )}
<p className="sub-text"> <p className="sub-text">
{mintedNFT} EpicNFTs on {maxNFT} already minted {mintedNFT} EpicNFTs on {maxNFT} already minted
</p> </p>
{link && ( {link && (
<p className="sub-text"> <p className="sub-text">
Hey there! We've minted your NFT. It may be blank right now. <br /> Hey there! We've minted your NFT. It may be blank right now. <br/>
It can take a max of 10 min to show up on OpenSea. Here's the{" "} It can take a max of 10 min to show up on OpenSea. Here's the{" "}
<a href={link} target="_blank" rel="noreferrer"> <a href={link} target="_blank" rel="noreferrer">
link link
</a> </a>
</p> </p>
)} )}
<button <button
className="cta-button connect-wallet-button" className="cta-button connect-wallet-button"
onClick={() => onClick={() =>
window.open( window.open(
"https://testnets.opensea.io/collection/squarenft-noshuqlivp", collectionAddress,
"_blank" "_blank"
) )
} }
> >
View Collection on OpenSea View Collection on OpenSea
</button> </button>
</div> </div>
</div>
</div>
</div> </div>
</div> );
</div>
);
} }
export default App; export default App;

View file

@ -1,8 +1,8 @@
import { render, screen } from '@testing-library/react'; import {render, screen} from '@testing-library/react';
import App from './App'; import App from './App';
test('renders learn react link', () => { test('renders learn react link', () => {
render(<App />); render(<App/>);
const linkElement = screen.getByText(/learn react/i); const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument(); expect(linkElement).toBeInTheDocument();
}); });

View file

@ -6,13 +6,13 @@ html {
body { body {
padding: 0; padding: 0;
font-family: -apple-system, Inter, BlinkMacSystemFont, 'Segoe UI', 'Roboto', font-family: -apple-system, Inter, BlinkMacSystemFont, 'Segoe UI', 'Roboto',
'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif; sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
code { code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace; monospace;
} }

View file

@ -1,14 +1,14 @@
import React from "react"; import React from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import reportWebVitals from "./reportWebVitals";
import App from "./App"; import App from "./App";
import "./index.css"; import "./index.css";
import reportWebVitals from "./reportWebVitals";
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
<App /> <App/>
</React.StrictMode>, </React.StrictMode>,
document.getElementById("root") document.getElementById("root")
); );
reportWebVitals(); reportWebVitals();

View file

@ -1,16 +1,16 @@
const getEth = () => { const getEth = () => {
const { ethereum } = window; const {ethereum} = window;
if (!ethereum) { if (!ethereum) {
alert("Wallet not detected. Make sure you have Metamask extension installed and activated."); alert("Wallet not detected. Make sure you have Metamask extension installed and activated.");
} }
return ethereum; return ethereum;
}; };
export const withEth = (f) => async (props) => { export const withEth = (f) => async (props) => {
try { try {
const ethereum = getEth(); const ethereum = getEth();
await f(ethereum, props); await f(ethereum, props);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }
}; };

View file

@ -1,13 +1,13 @@
const reportWebVitals = onPerfEntry => { const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) { if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { import('web-vitals').then(({getCLS, getFID, getFCP, getLCP, getTTFB}) => {
getCLS(onPerfEntry); getCLS(onPerfEntry);
getFID(onPerfEntry); getFID(onPerfEntry);
getFCP(onPerfEntry); getFCP(onPerfEntry);
getLCP(onPerfEntry); getLCP(onPerfEntry);
getTTFB(onPerfEntry); getTTFB(onPerfEntry);
}); });
} }
}; };
export default reportWebVitals; export default reportWebVitals;

View file

@ -2,4 +2,4 @@
// allows you to do things like: // allows you to do things like:
// expect(element).toHaveTextContent(/react/i) // expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom // learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';

View file

@ -11,83 +11,82 @@ contract EpicNFT is ERC721URIStorage {
Counters.Counter private _tokenIds; Counters.Counter private _tokenIds;
event NewEpicNFTMinted(address sender, uint256 tokenID); event NewEpicNFTMinted(address sender, uint256 tokenID);
uint256 private maxTokenAllowed = 50;
uint256 private constant MAX_NFT_ALLOWED = 50;
constructor() ERC721("SquareNFT", "SQUARE") { constructor() ERC721("SquareNFT", "SQUARE") {
console.log("My first NFT contract! EPIC!!!"); console.log("My first NFT contract! EPIC!!!");
} }
string baseSvg1 = string baseSvg1 = "<svg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='xMinYMin meet' viewBox='0 0 350 350'><style>.base { fill:";
"<svg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='xMinYMin meet' viewBox='0 0 350 350'><style>.base { fill:";
string baseSvg2 = string baseSvg2 = "; font-family: serif; font-size: 24px; }</style><rect width='100%' height='100%' fill='black' /><text x='50%' y='50%' class='base' dominant-baseline='middle' text-anchor='middle'>";
"; font-family: serif; font-size: 24px; }</style><rect width='100%' height='100%' fill='black' /><text x='50%' y='50%' class='base' dominant-baseline='middle' text-anchor='middle'>";
string[] colors = [ string[] colors = [
"red", "red",
"green", "green",
"blue", "blue",
"white", "white",
"yellow", "yellow",
"cyan", "cyan",
"pink", "pink",
"magenta", "magenta",
"silver", "silver",
"gold" "gold"
]; ];
string[] levels = [ string[] levels = [
"Epic", "Epic",
"Legendary", "Legendary",
"Heroic", "Heroic",
"Cool", "Cool",
"Fantastic", "Fantastic",
"Terrible", "Terrible",
"Crazy", "Crazy",
"Wild", "Wild",
"Terrifying", "Terrifying",
"Spooky" "Spooky"
]; ];
string[] classes = [ string[] classes = [
"Assassin", "Assassin",
"Cleric", "Cleric",
"Rogue", "Rogue",
"Ninja", "Ninja",
"Lord", "Lord",
"Wizard", "Wizard",
"Warrior", "Warrior",
"Berserker", "Berserker",
"Necromander", "Necromander",
"Summoner", "Summoner",
"Bard", "Bard",
"Lancer" "Lancer"
]; ];
string[] jobs = [ string[] jobs = [
"Soldier", "Soldier",
"Healer", "Healer",
"Explorer", "Explorer",
"Merchant", "Merchant",
"Developer", "Developer",
"BlackSmith", "BlackSmith",
"Hitman", "Hitman",
"Cook", "Cook",
"Hunter", "Hunter",
"Sailor" "Sailor"
]; ];
function nftMintedCount() public view returns (uint256) { function nftMintedCount() public view returns (uint256) {
return _tokenIds.current(); return _tokenIds.current();
} }
function getMaxNFTAllowed() public view returns(uint){ function getMaxNFTAllowed() public pure returns (uint) {
return maxTokenAllowed; return MAX_NFT_ALLOWED;
} }
function mint() public { function mint() public {
require( require(
_tokenIds.current() < maxTokenAllowed, _tokenIds.current() < MAX_NFT_ALLOWED,
"the maximum of EpicNFT has already been minted" "the maximum of EpicNFT has already been minted"
); );
uint256 tokenID = _tokenIds.current(); uint256 tokenID = _tokenIds.current();

View file

@ -12,7 +12,7 @@ pragma solidity ^0.8.0;
/// @author Brecht Devos <brecht@loopring.org> /// @author Brecht Devos <brecht@loopring.org>
library Base64 { library Base64 {
bytes internal constant TABLE = bytes internal constant TABLE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/// @notice Encodes some bytes to the base64 representation /// @notice Encodes some bytes to the base64 representation
function encode(bytes memory data) internal pure returns (string memory) { 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))) let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
out := shl(8, out) out := shl(8, out)
out := add( out := add(
out, out,
and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF) and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)
) )
out := shl(8, out) out := shl(8, out)
out := add( out := add(
out, out,
and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF) and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)
) )
out := shl(8, out) out := shl(8, out)
out := add( out := add(
out, out,
and(mload(add(tablePtr, and(input, 0x3F))), 0xFF) and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)
) )
out := shl(224, out) out := shl(224, out)

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

View file

@ -1,27 +1,27 @@
const { ethers } = require("hardhat"); // this import is optional const {ethers} = require("hardhat"); // this import is optional
async function main() { async function main() {
const EpicNFT = await ethers.getContractFactory("EpicNFT"); const EpicNFT = await ethers.getContractFactory("EpicNFT");
const contract = await EpicNFT.deploy(); const contract = await EpicNFT.deploy();
await contract.deployed(); await contract.deployed();
console.log("EpicNFT deployed to:", contract.address); console.log("EpicNFT deployed to:", contract.address);
let txn = await contract.mint(); let txn = await contract.mint();
await txn.wait(); await txn.wait();
console.log("Mint NFT #1"); console.log("Mint NFT #1");
txn = await contract.mint(); txn = await contract.mint();
await txn.wait(); await txn.wait();
console.log("Mint NFT #2"); console.log("Mint NFT #2");
} }
// run the script // run the script
(async () => { (async () => {
try { try {
await main(); await main();
process.exit(0); process.exit(0);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
process.exit(1); process.exit(1);
} }
})(); })();

View file

@ -1,34 +1,34 @@
const { ethers } = require("hardhat"); // this import is optional const {ethers} = require("hardhat"); // this import is optional
async function main() { async function main() {
const EpicNFT = await ethers.getContractFactory("EpicNFT"); const EpicNFT = await ethers.getContractFactory("EpicNFT");
const contract = await EpicNFT.deploy(); const contract = await EpicNFT.deploy();
await contract.deployed(); await contract.deployed();
console.log("EpicNFT deployed to:", contract.address); console.log("EpicNFT deployed to:", contract.address);
let count = await contract.nftMintedCount(); let count = await contract.nftMintedCount();
console.log(count.toNumber()); console.log(count.toNumber());
let txn = await contract.mint(); let txn = await contract.mint();
await txn.wait(); await txn.wait();
count = await contract.nftMintedCount(); count = await contract.nftMintedCount();
console.log(count.toNumber()); console.log(count.toNumber());
txn = await contract.mint(); txn = await contract.mint();
await txn.wait(); await txn.wait();
count = await contract.nftMintedCount(); count = await contract.nftMintedCount();
console.log(count.toNumber()); console.log(count.toNumber());
} }
// run the script // run the script
(async () => { (async () => {
try { try {
await main(); await main();
process.exit(0); process.exit(0);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
process.exit(1); process.exit(1);
} }
})(); })();