Cloud function wraps my JSON in "result" not allowing it to be used for smart contract

Hi! I am quite new to all of this, and after spending countless hours on rendering NFT’s, uploading them to Moralis DB, writing cloud function and smart contract, I found myself facing a problem I cannot solve.

So the project I am working on is supposed to be game, storing NFT uri data on the Moralis server so it can easily be changed as the player progresses. Here is my cloud function:

Moralis.Cloud.define("GetNFT", async (request) => {
  const query = new Moralis.Query("Farmer");
  query.equalTo("Id", parseInt(request.params.id));
  const res = await query.first();

  const image = res.get("Image");
  const map1 = new Map(Object.entries(image));
  
  metadata = {
	"name": `Farmer #${request.params.id}`,
	"description": "“The Farmers” is an NFT collection that contains 5555 unique, computer-generated little characters.  Besides being collectibles these tokens are also your key to unlocking the wonders of Farmverse – a multiplayer play-to-earn online video game.",
	"image": Object.entries(image)[3][1],
	"properties": {
		"appearance": {
			"Skin color":  res.get("SkinColor"),
          	"Eye color": res.get("EyeColor"),
			"Accessory": res.get("Accessory"),
			"Hat": res.get("Hat"),
			"Pants": res.get("Pants"),
          	"Shoes": res.get("Shoes"),
          	"Shirt": res.get("Shirt"),
          	"Setting": res.get("Setting"),
		},
      	"statistics": {
			"Tenacity":  res.get("Tenacity"),
          	"Strength": res.get("Strength"),
			"Agility": res.get("Agility"),
			"Intelligence": res.get("Intelligence"),
			"Luck": res.get("Luck"),
		},
	}
};
  
  return metadata;
});

And it produces the following JSON, using a link that can be found in the documentation.

{"result":{"name":"Farmer #6","description":"“The Farmers” is an NFT collection that contains 5555 unique, computer-generated little characters.  Besides being collectibles these tokens are also your key to unlocking the wonders of Farmverse – a multiplayer play-to-earn online video game.","image":"https://wafhxjairicm.usemoralis.com:2053/server/files/7YsTADQstpGlcRj3pXOMVV8crTBdklv8XehAxyrf/5cb4e86f7ee47025052e5f5dffc15b8f_Farmer6.jpg","properties":{"appearance":{"Skin color":"Sienna","Eye color":"Black","Accessory":"Brown Pipe","Hat":"White Fisherman's Hat","Pants":"Light Blue Pants Brown Belt","Shoes":"Purple Bowling Shoes","Shirt":"Brown Turtle Neck","Setting":"Setting #3"},"statistics":{"Tenacity":13.2,"Strength":14.4,"Agility":9.4,"Intelligence":11.6,"Luck":19.6}}}}

After I got the cloud to produce this link, I pasted it in my smart contract like this:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/[email protected]/token/ERC1155/ERC1155.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";

contract FarmerNFT is ERC1155, Ownable {

    uint256 supply = 5555;
    uint256 minted = 6;
    uint256 rate = 0.01 ether;

    constructor()
        ERC1155("https://wafhxjairicm.usemoralis.com:2053/server/functions/GetNFT?_ApplicationId=7YsTADQstpGlcRj3pXOMVV8crTBdklv8XehAxyrf&id={id}")
    {}

    function setURI(string memory newuri) public onlyOwner {
        _setURI(newuri);
    }

    function mint()
        public
        payable
    {
        require(minted <= supply, "All tokens have been minted");
        require(msg.value >= rate, "Not enough ether sent");
        _mint(msg.sender, minted,  1, "");
        minted += 1;
    }


    function mintPrivate(address account, uint256 id)
        public
        onlyOwner
    {   
        _mint(account, id, 1, "");
    }

    function withdraw() public onlyOwner{
        require(address(this).balance > 0, "Balance is 0");
        payable(owner()).transfer(address(this).balance);
    }
    function getCounter() public view returns(uint256 counter){
        return minted;
    }

}

I did this whole thing following an official tutorial that surely cannot be misleading! (https://www.youtube.com/watch?v=02VnfTIomn8&ab_channel=MoralisWeb3)

Anyways, so, after doing all of these steps and deploying my smart contract, I end up with a bad result. Neither metamask, opensea or any other websites that use metadata dont cannot find it. I even used some metadata checkers and they all say that “this token uses non-standard metadata format”. This leads me to believe, that the “result” tag, which wraps my cloud JSON is at fault. I have been informed by Moralis staff that it is in fact impossible to remove that tag.

So I want to ask, can anyone please proved me with a usable solution to this problem? I cam quite a long way and it seems ridiculous that Moralis functionality would harm, instrad of helping my project.

Solutiuons i have tried:
PArsing the JSON in smart contract - expensive and doesn’t update
Storing in the IPFS - very hard and expensive to update.

I also want to keep using Moralis, because it has integration with react, js AND unity, making it very convienent for my project. Any advice helps. Please.

Definitely don’t do the work in the smart contract.

Fetch GetNFT, select result from the response and then pass the straight data to your contract from your frontend or backend (not statically like you’ve done).

That would be a good solution, but I need the metadata to always update itself when the server is updated. Minting a link to the Uri would accomplish just that. On the other hand, if I were to fetch the result and pass on the JSON the data would be set and not change unless changed manually. Correct?

Is there any way to get rid of the “result” on the moralis cloud side of things? So i could just keep passing a link with changable id’s?

I see. You probably have to use your own server or API that queries Moralis for this data, and then parses it for you and returns it, acting as the URI. I can’t think of another way unless Moralis has some other built-in option.

So the constructor would be https://viliusgame.com/GetNFT_ApplicationId=7YsTADQstpGlcRj3pXOMVV8crTBdklv8XehAxyrf&id={id} and queries for the data and transforms it on the way back.

If all cloud functions do the same thing with result then you probably have to look at doing something like this.

1 Like