Creating a front‐end DApp using React - CreoDAMO/CQTSOG-MMORPG GitHub Wiki

Creating a Front-end DApp for CryptoQuest

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.

Setting Up Your Development Environment

Ensure you have Node.js and npm installed. Then, create a new React app:

npx create-react-app cryptoquest-dapp
cd cryptoquest-dapp

Install Dependencies

Install the necessary packages to interact with the Ethereum blockchain:

npm install ethers web3modal @web3-react/core @web3-react/injected-connector

Create a Config File for Your Contracts

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";

Set Up Web3Modal for Wallet Connection

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;
};

Create Context for Web3

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>
    );
};

Interacting with Smart Contracts

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 UI Components

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;

Integrate Components into the App

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;

Run Your DApp

Start your React app:

npm start

How to Use the Makefile

  1. Install Dependencies:

    make install
  2. Start the Development Server:

    make start
  3. Build the Project:

    make build
  4. Run Tests:

    make test
  5. Lint the Code:

    make lint
  6. Format the Code:

    make format
  7. Clean the Project:

    make clean
  8. Set Up the Development Environment:

    make setup
  9. Initialize IPFS:

    make ipfs-init
  10. Start the IPFS Daemon:

    make ipfs-start
  11. Add a File to IPFS:

    make ipfs-add FILE=<file-path>
  12. Pin a File on IPFS:

    make ipfs-pin CID=<cid>
  13. Upload a File to Infura IPFS:

    make infura-add FILE=<file-path>
  14. Pin a File on Infura IPFS:

    make infura-pin CID=<cid>

Contract Information

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

Step 2: Place the Token Logo in the Asset Folder

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

Step 3: Convert PNG Images to SVG

To convert these PNG images to SVG format, you can use online tools like Online Convert or use Inkscape on your local machine.

Using Inkscape (on your local machine):

  1. Install Inkscape: Download and install Inkscape from here.
  2. 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.

⚠️ **GitHub.com Fallback** ⚠️