Creating a front‐end DApp using React - CreoDAMO/CQTSOG-MMORPG GitHub Wiki
Creating a front-end DApp using React to interact with all 23 smart contracts in this project is a crucial step. Here’s a step-by-step guide, updated to match the current file structure.
Ensure you have Node.js and npm installed. Then, create a new React app:
npx create-react-app cryptoquest-dapp
cd cryptoquest-dapp
Install the necessary packages to interact with the Ethereum blockchain:
npm install ethers web3modal @web3-react/core @web3-react/injected-connector
Set up a folder and file to store your contract ABIs and addresses:
mkdir src/contracts
touch src/contracts/index.js
In src/contracts/index.js
:
import CryptoQuestTheShardsOfGenesisMMPORPG from './CryptoQuestTheShardsOfGenesisMMPORPG.json';
import CryptoQuestTheShardsOfGenesisToken from './CryptoQuestTheShardsOfGenesisToken.json';
import CryptoQuestSwap from './CryptoQuestSwap.json';
import CryptoQuestShardsOfGenesisFarming from './CryptoQuestShardsOfGenesisFarming.json';
import CryptoQuestTheShardsOfGenesis1155 from './CryptoQuestTheShardsOfGenesis1155.json';
import CryptoQuestTheShardsOfGenesisBookNFT from './CryptoQuestTheShardsOfGenesisBookNFT.json';
import CryptoQuestTheShardsOfGenesisCollectionNFTs from './CryptoQuestTheShardsOfGenesisCollectionNFTs.json';
import CryptoQuestTheShardsOfGenesisDAO from './CryptoQuestTheShardsOfGenesisDAO.json';
import CryptoQuestTheShardsOfGenesisMarketplace from './CryptoQuestTheShardsOfGenesisMarketplace.json';
import CryptoQuestTheShardsOfGenesisStaking from './CryptoQuestTheShardsOfGenesisStaking.json';
import CryptoQuestTheShardsOfGenesisWallet from './CryptoQuestTheShardsOfGenesisWallet.json';
export const CryptoQuestTheShardsOfGenesisMMPORPG_ABI = CryptoQuestTheShardsOfGenesisMMPORPG.abi;
export const CryptoQuestTheShardsOfGenesisToken_ABI = CryptoQuestTheShardsOfGenesisToken.abi;
export const CryptoQuestSwap_ABI = CryptoQuestSwap.abi;
export const CryptoQuestShardsOfGenesisFarming_ABI = CryptoQuestShardsOfGenesisFarming.abi;
export const CryptoQuestTheShardsOfGenesis1155_ABI = CryptoQuestTheShardsOfGenesis1155.abi;
export const CryptoQuestTheShardsOfGenesisBookNFT_ABI = CryptoQuestTheShardsOfGenesisBookNFT.abi;
export const CryptoQuestTheShardsOfGenesisCollectionNFTs_ABI = CryptoQuestTheShardsOfGenesisCollectionNFTs.abi;
export const CryptoQuestTheShardsOfGenesisDAO_ABI = CryptoQuestTheShardsOfGenesisDAO.abi;
export const CryptoQuestTheShardsOfGenesisMarketplace_ABI = CryptoQuestTheShardsOfGenesisMarketplace.abi;
export const CryptoQuestTheShardsOfGenesisStaking_ABI = CryptoQuestTheShardsOfGenesisStaking.abi;
export const CryptoQuestTheShardsOfGenesisWallet_ABI = CryptoQuestTheShardsOfGenesisWallet.abi;
export const CryptoQuestTheShardsOfGenesisMMPORPG_ADDRESS = "0x251ace49f2b106e0746702986e879e404a76f290";
export const CryptoQuestTheShardsOfGenesisToken_ADDRESS = "0xb30837f54924b88294f524d3e13667396d3f3c8a";
export const CryptoQuestSwap_ADDRESS = "0x7132367941b5f058dc68cee2dbcd356fbaa7d5b4";
export const CryptoQuestShardsOfGenesisFarming_ADDRESS = "0x822475be2d1b53680ceb3da287a7c608fed591a4";
export const CryptoQuestTheShardsOfGenesis1155_ADDRESS = "0x5ce6de14eaa1906163c5de4e57302fee8f5d2812";
export const CryptoQuestTheShardsOfGenesisBookNFT_ADDRESS = "0x545Ace061A1b64B14641B50CfE317017b01A667b";
export const CryptoQuestTheShardsOfGenesisCollectionNFTs_ADDRESS = "0x5ce6de14eaa1906163c5de4e57302fee8f5d2812";
export const CryptoQuestTheShardsOfGenesisDAO_ADDRESS = "0x7c3dddd47c29d213458abf9eb23fe50d95fa5205";
export const CryptoQuestTheShardsOfGenesisMarketplace_ADDRESS = "0xef805704fd13b0122477211895e418cb9c22e103";
export const CryptoQuestTheShardsOfGenesisStaking_ADDRESS = "0x7ffc728c30192bf6f2f1448e395a8c9f751bc039";
export const CryptoQuestTheShardsOfGenesisWallet_ADDRESS = "0xf60d96cfa71c6fe7fe18ca028041ca7f42b543bd";
Create a new file src/utils/web3Modal.js
to manage wallet connections:
import Web3Modal from "web3modal";
import { ethers } from "ethers";
import { InjectedConnector } from "@web3-react/injected-connector";
import { Web3Provider } from "@ethersproject/providers";
export const injected = new InjectedConnector({
supportedChainIds: [1, 3, 4, 5, 42]
});
export const web3Modal = new Web3Modal({
cacheProvider: true,
providerOptions: {}
});
export const getLibrary = (provider) => {
const library = new Web3Provider(provider);
library.pollingInterval = 12000;
return library;
};
Set up a Web3Context
to manage web3 state across your app:
mkdir src/context
touch src/context/Web3Context.js
In src/context/Web3Context.js
:
import React, { createContext, useState, useEffect } from 'react';
import { ethers } from 'ethers';
import { web3Modal, getLibrary } from '../utils/web3Modal';
export const Web3Context = createContext();
export const Web3Provider = ({ children }) => {
const [provider, setProvider] = useState(null);
const [library, setLibrary] = useState(null);
const [account, setAccount] = useState(null);
const [chainId, setChainId] = useState(null);
const connect = async () => {
const instance = await web3Modal.connect();
const library = getLibrary(instance);
const accounts = await library.listAccounts();
const network = await library.getNetwork();
setProvider(instance);
setLibrary(library);
if (accounts) setAccount(accounts[0]);
setChainId(network.chainId);
};
const disconnect = async () => {
web3Modal.clearCachedProvider();
setProvider(null);
setLibrary(null);
setAccount(null);
setChainId(null);
};
useEffect(() => {
if (web3Modal.cachedProvider) {
connect();
}
}, []);
return (
<Web3Context.Provider value={{ connect, disconnect, provider, library, account, chainId }}>
{children}
</Web3Context.Provider>
);
};
Set up functions to interact with your smart contracts in src/utils/contracts.js
:
import { ethers } from 'ethers';
import {
CryptoQuestTheShardsOfGenesisMMPORPG_ABI,
CryptoQuestTheShardsOfGenesisToken_ABI,
CryptoQuestSwap_ABI,
CryptoQuestTheShardsOfGenesisMMPORPG_ADDRESS,
CryptoQuestTheShardsOfGenesisToken_ADDRESS,
CryptoQuestSwap_ADDRESS,
CryptoQuestShardsOfGenesisFarming_ABI,
CryptoQuestShardsOfGenesisFarming_ADDRESS,
CryptoQuestTheShardsOfGenesis1155_ABI,
CryptoQuestTheShardsOfGenesis1155_ADDRESS,
CryptoQuestTheShardsOfGenesisBookNFT_ABI,
CryptoQuestTheShardsOfGenesisBookNFT_ADDRESS,
CryptoQuestTheShardsOfGenesisCollectionNFTs_ABI,
CryptoQuestTheShardsOfGenesisCollectionNFTs_ADDRESS,
CryptoQuestTheShardsOfGenesisDAO_ABI,
CryptoQuestTheShardsOfGenesisDAO_ADDRESS,
CryptoQuestTheShardsOfGenesisMarketplace_ABI,
CryptoQuestTheShardsOfGenesisMarketplace_ADDRESS,
CryptoQuestTheShardsOfGenesisStaking_ABI,
CryptoQuestTheShardsOfGenesisStaking_ADDRESS,
CryptoQuestTheShardsOfGenesisWallet_ABI,
CryptoQuestTheShardsOfGenesisWallet_ADDRESS,
} from '../contracts';
export const getContract = (abi, address, library) => {
const signer = library.getSigner();
return new ethers.Contract(address, abi, signer);
};
export const getCryptoQuestTheShardsOfGenesisMMPORPGContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisMMPORPG_ABI, CryptoQuestTheShardsOfGenesisMMPORPG_ADDRESS, library);
};
export const getCryptoQuestThe
ShardsOfGenesisTokenContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisToken_ABI, CryptoQuestTheShardsOfGenesisToken_ADDRESS, library);
};
export const getCryptoQuestSwapContract = (library) => {
return getContract(CryptoQuestSwap_ABI, CryptoQuestSwap_ADDRESS, library);
};
export const getCryptoQuestShardsOfGenesisFarmingContract = (library) => {
return getContract(CryptoQuestShardsOfGenesisFarming_ABI, CryptoQuestShardsOfGenesisFarming_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesis1155Contract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesis1155_ABI, CryptoQuestTheShardsOfGenesis1155_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesisBookNFTContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisBookNFT_ABI, CryptoQuestTheShardsOfGenesisBookNFT_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesisCollectionNFTsContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisCollectionNFTs_ABI, CryptoQuestTheShardsOfGenesisCollectionNFTs_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesisDAOContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisDAO_ABI, CryptoQuestTheShardsOfGenesisDAO_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesisMarketplaceContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisMarketplace_ABI, CryptoQuestTheShardsOfGenesisMarketplace_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesisStakingContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisStaking_ABI, CryptoQuestTheShardsOfGenesisStaking_ADDRESS, library);
};
export const getCryptoQuestTheShardsOfGenesisWalletContract = (library) => {
return getContract(CryptoQuestTheShardsOfGenesisWallet_ABI, CryptoQuestTheShardsOfGenesisWallet_ADDRESS, library);
};
Create React components to interact with the contracts. For example, a component for the main game contract:
mkdir src/components
touch src/components/Game.js
In src/components/Game.js
:
import React, { useContext, useState } from 'react';
import { Web3Context } from '../context/Web3Context';
import { getCryptoQuestTheShardsOfGenesisMMPORPGContract } from '../utils/contracts';
const Game = () => {
const { library, account } = useContext(Web3Context);
const [player, setPlayer] = useState(null);
const createPlayer = async () => {
const contract = getCryptoQuestTheShardsOfGenesisMMPORPGContract(library);
const tx = await contract.createPlayer();
await tx.wait();
};
const fetchPlayer = async () => {
const contract = getCryptoQuestTheShardsOfGenesisMMPORPGContract(library);
const player = await contract.players(account);
setPlayer(player);
};
return (
<div>
<button onClick={createPlayer}>Create Player</button>
<button onClick={fetchPlayer}>Fetch Player</button>
{player && (
<div>
<p>Level: {player.level}</p>
<p>Experience: {player.experience}</p>
</div>
)}
</div>
);
};
export default Game;
Add your components to App.js
:
import React from 'react';
import { Web3Provider } from './context/Web3Context';
import Game from './components/Game';
function App() {
return (
<Web3Provider>
<div className="App">
<h1>CryptoQuest: The Shards of Genesis</h1>
<Game />
</div>
</Web3Provider>
);
}
export default App;
Start your React app:
npm start
-
Install Dependencies:
make install
-
Start the Development Server:
make start
-
Build the Project:
make build
-
Run Tests:
make test
-
Lint the Code:
make lint
-
Format the Code:
make format
-
Clean the Project:
make clean
-
Set Up the Development Environment:
make setup
-
Initialize IPFS:
make ipfs-init
-
Start the IPFS Daemon:
make ipfs-start
-
Add a File to IPFS:
make ipfs-add FILE=<file-path>
-
Pin a File on IPFS:
make ipfs-pin CID=<cid>
-
Upload a File to Infura IPFS:
make infura-add FILE=<file-path>
-
Pin a File on Infura IPFS:
make infura-pin CID=<cid>
Contract Name | Address | Network | Tags | Visibility | Verification |
---|---|---|---|---|---|
CryptoQuestTheShardsOfGenesisToken | 0xb30837f54924b88294f524d3e13667396d3f3c8a | Polygon | Visible | Public | Verified |
ERC1967Proxy (CQT) | 0xb30837f54924b88294f524d3e13667396d3f3c8a | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisNFT | 0xc641573148e62d88a2374ffe97391f849cea8ff5 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0xc641573148e62d88a2374ffe97391f849cea8ff5 | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisCollectionNFT | 0x5ce6de14eaa1906163c5de4e57302fee8f5d2812 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0x5ce6de14eaa1906163c5de4e57302fee8f5d2812 | Polygon | Visible | Public | Verified |
TimelockControllerUpgradeable | 0x2b5949f0540884c67c1f169b9f535571656e6695 | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisDAO | 0x7c3dddd47c29d213458abf9eb23fe50d95fa5205 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0x7c3dddd47c29d213458abf9eb23fe50d95fa5205 | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisMarketplace | 0xef805704fd13b0122477211895e418cb9c22e103 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0xef805704fd13b0122477211895e418cb9c22e103 | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisStaking | 0x7ffc728c30192bf6f2f1448e395a8c9f751bc039 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0x7ffc728c30192bf6f2f1448e395a8c9f751bc039 | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisFarming | 0x822475be2d1b53680ceb3da287a7c608fed591a4 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0x822475be2d1b53680ceb3da287a7c608fed591a4 | Polygon | Visible | Public | Verified |
CryptoQuestTheShardsOfGenesisMMORPG | 0x251ace49f2b106e0746702986e879e404a76f290 | Polygon | Visible | Public | Verified |
ERC1967Proxy | 0x251ace49f2b106e074670298 |
6e879e404a76f290 | Polygon | Visible | Public | Verified | | CryptoQuestTheShardsOfGenesisWallet | 0xf60d96cfa71c6fe7fe18ca028041ca7f42b543bd | Polygon | Visible | Public | Verified | | ERC1967Proxy | 0xf60d96cfa71c6fe7fe18ca028041ca7f42b543bd | Polygon | Visible | Public | Verified | | CryptoQuestSwap | 0x7132367941b5f058dc68cee2dbcd356fbaa7d5b4 | Polygon | Visible | Public | Verified | | ERC1967Proxy | 0x7132367941b5f058dc68cee2dbcd356fbaa7d5b4 | Polygon | Visible | Public | Verified | | CryptoQuestTheShardsOfGenesisBookNFT | 0x545Ace061A1b64B14641B50CfE317017b01A667b | Polygon | Visible | Public | Verified | | ERC1967Proxy | 0x6b07aD60b1d448D0e1cE9dCB24A85B3ab18b9b1E | Polygon | Visible | Public | Verified |
---
### **Assets Management**
1. **Place the Game Logo in the Public Folder**
2. **Place the Token Logo in the Asset Folder**
3. **Convert PNG Images to SVG**
### Step 1: Place the Game Logo in the Public Folder
Move the game logo (`CQTSOG-Logo.png`) to the public folder:
```bash
# Move the game logo to the public folder
mv /mnt/data/CQTSOG-Logo.png public/CQTSOG-Logo.png
Move the token logo (CQTSOG-Token-Logo.png
) to the asset folder:
# Move the token logo to the asset folder
mv /mnt/data/CQTSOG-Token-Logo.png src/assets/CQTSOG-Token-Logo.png
To convert these PNG images to SVG format, you can use online tools like Online Convert or use Inkscape on your local machine.
- Install Inkscape: Download and install Inkscape from here.
-
Convert the PNG images to SVG:
# Convert the game logo inkscape public/CQTSOG-Logo.png --export-plain-svg=public/CQTSOG-Logo.svg # Convert the token logo inkscape src/assets/CQTSOG-Token-Logo.png --export-plain-svg=src/assets/CQTSOG-Token-Logo.svg
After conversion, ensure the SVG files are correctly placed in the public
and src/assets
directories. The updated structure should look like this:
public/
├── CQTSOG-Logo.png
├── CQTSOG-Logo.svg
src/assets/
├── CQTSOG-Token-Logo.png
├── CQTSOG-Token-Logo.svg
You can then reference these SVG files in your React project as needed.