/moralis-nft-game

Primary LanguageJavaScriptMIT LicenseMIT

NFT Game Logic Sandbox

React components and hooks for fast testing game logic with Moralis.

About

Aim: Save time and resources for game developers by e.g. facilitating the generation of in-game assets as NFTs via intuative UI.

Built on react-moralis and Moralis.

These tutorial videos are a great introduction.
Part 1: Link to Moralis YouTube Video
Part 2: Link to Moralis YouTube Video
Part 3: Link to Moralis YouTube Video
Part 4: Link to Moralis YouTube Video

Further Watching

NFT Game Design Principles
Build an NFT Game Smart Contract


Quick Launch 🚀

Via terminal, navigate to your local dev directory and run:

git clone https://github.com/ashbeech/moralis-nft-game.git

Then navigate into the cloned project's root directory to install all dependencies:

npm install

Go to Moralis.io to create your server instance. Rename .env.example file to .env and add your Moralis server credentials. For help see 'How to start Moralis Server'.

Note: To find your "X-API-Key": API_KEY here: https://deep-index.moralis.io/api-docs/#/storage/uploadFolder

Run your app:

npm start

Functionality 🛠

IPFS Metadata Uploads

Using axios lib, pointed at the API_URL you can upload files directly to IPFS.

// upload to IPFS
Promise.all(promiseArray).then(() => {
  axios
    .post(API_URL, ipfsArray, {
      headers: {
        "X-API-Key": API_KEY,
        "content-type": "application/json",
        accept: "application/json",
      },
    })
    .then((res) => {
      // successfully uploaded file to IPFS
      let fileCID = res.data[0].path.split("/")[4];
      console.log("FILE CID:", fileCID);
      // pass IPFS folder CID to compile metadata
      uploadMetadata(
        API_URL, // <-- this is in .env
        API_KEY, // <-- this is in .env
        fileCID,
        totalFiles,
        _formValues,
      );
    })
    .catch((err) => {
      setLoading(false);
      setError(true);
      setErrorMessage(err);
      console.log(err);
    });
});

useWeb3ExecuteFunction()

You can use the useWeb3ExecuteFunction() hook to execute on-chain functions. You need to provide the correct abi of the contract, the corresponding contractAddress, the functionName that you would like to execute, and any parameters (params) thet you need to send with the function.

const mintCharacter = async (_metaCID, _id, _formValues) => {
  // could be _mintAmount instead(?) i.e. 1 is just temp hardcoded
  let _url = "";
  let paddedHex = (
    "0000000000000000000000000000000000000000000000000000000000000000" + _id
  ).slice(-64);
  _url = `https://ipfs.moralis.io:2053/ipfs/${_metaCID}/metadata/${paddedHex}.json`;

  // set link for verifibility at end of upload -> mint process
  setIPFSLinkImage(_url);

  const options = {
    abi: charContractAbi,
    contractAddress: CHAR_CONTRACT,
    functionName: "mintToken",
    params: {
      _mintAmount: 1,
      _damage: _formValues.damage,
      _power: _formValues.power,
      _endurance: _formValues.endurance,
      _tokenURI: _url,
    },
  };

  console.log("META DATA URL:", _url);

  await fetch({
    params: options,
    onSuccess: (response) => setInteractionData(response),
    onComplete: () => console.log("MINT COMPLETE"),
    onError: (error) => console.log("ERROR", error),
  });
};

Minting Game Assets ⛓

Deploy Solidity contracts e.g. Character.sol to EVM blockchain via Truffle (local) or ⚙️ Remix IDE for test or mainnet deployment.

Metadata uploaded to IPFS (_tokenURI) is mapped to a token's ID via the inherited _setTokenURI function from openzeppelin:

    function mintToken(
        uint256 _mintAmount,
        uint8 _damage,
        uint8 _power,
        uint256 _endurance,
        string memory _tokenURI
    ) public payable onlyOwner mintCompliance(_mintAmount) returns (uint256) {
        _tokenIDS.increment();

        uint256 newCharID = _tokenIDS.current();
        _tokenDetails[newCharID] = CharData(
            newCharID,
            _damage,
            _power,
            block.timestamp,
            _endurance,
            _tokenURI
        );

        for (uint256 i = 1; i <= _mintAmount; i++) {
            addressMintedBalance[msg.sender]++;
        }

        _safeMint(msg.sender, newCharID);
        _setTokenURI(newCharID, _tokenURI);

        return newCharID;
    }

Much more to come [WIP]


Dependencies 🏗

Backend

moralis: ℹ️ Docs
react-moralis: ℹ️ Docs
axios: ℹ️ Docs
openzeppelin: ℹ️ Docs

Frontend

chakra-ui: ℹ️ Docs
react-dropzone: ℹ️ Docs


🤝 Need help?

If you need help with setting up the app or have other questions - don't hesitate to write in our community forum and we will check asap. Forum link. The best thing about Moralis is the super active community ready to help at any time! We help each other.

⭐️ Star us

If this code brought you value, please star this project.

This is bullish.