Finding EthTokenBalance -- I CLONED RARIBLE IN 24H - Cloud functions [PART 8]

How am i to find the EthTokenBalance in my Moralis database?
These are my current classes…
Screenshot 2022-06-28 144340

You can use the web3Api to fetch the token balance. xxxTokenBalance classes are removed from the database.

https://docs.moralis.io/moralis-dapp/web3-api/account#gettokenbalances

so how exactly would i implement this into my code?

I haven’t looked at this project code yet. If the code uses a database query to fetch the balance from EthTokenBalance, then remove this code and replace it with getTokenBalances function to fetch the token balances from eth chain.

There is no database query being used to fetch from EthTokenBalance.
This is my code here if it helps:

JS:


// https://didzlxt4karo.usemoralis.com:2083/apps/moralisDashboard/browser/_AddressSyncStatus
const serverUrl = "https://u2qkea8vtbas.usemoralis.com:2053/server";
const appId = "tEidQRu3pY96IBc4hXI7phHbyupE6Ts6TkLi5vFq";
const TOKEN_CONTRACT_ADDRESS = "0x904fE54f1b5Eaa1621B31B05642EDd1fb43555F5"
Moralis.start({ serverUrl, appId, TOKEN_CONTRACT_ADDRESS });

init = async () => {
    hideElement(userItemsSection);
    hideElement(userInfo);
    hideElement(createItemForm);
    await Moralis.enableWeb3();

    web3 = new Web3(web3.currentProvider);

    window.tokenContract = new web3.eth.Contract(
        tokenContractAbi, 
        TOKEN_CONTRACT_ADDRESS
        );
        initUser();
};

initUser = async () => {
    if (await Moralis.User.current()){
        hideElement(firstTip);
        showElement(secondTip);
        hideElement(userConnectButton);
        showElement(userProfileButton);
        showElement(openCreateItemButton);
        showElement(openUserItemsButton);

    }else{
        showElement(firstTip);
        hideElement(secondTip);
        showElement(userConnectButton);
        hideElement(userProfileButton);
        hideElement(openCreateItemButton);
        hideElement(createItemForm);
        hideElement(openUserItemsButton);
    }
}

login = async () => {
    try {
        await Moralis.authenticate();
        initUser();
    } catch (error) {
        if (error.code == '4001'){
            alert(error.code + ": To connect your wallet to this site, you must confirm sign.");
        }
        
    }
}

logout = async () => {
    await Moralis.User.logOut();
    hideElement(userInfo);
    initUser();
}

openUserInfo = async () => {
    
    user = await Moralis.User.current();
    if (user){    
        const email = user.get('email');
        if(email){
            userEmailField.value = email;
        }else{
            userEmailField.value = "";
        }

        userNameField.value = user.get('username');

        const userAvatar = user.get('avatar');
        if(userAvatar){
            userAvatarImg.src = userAvatar.url();
            showElement(userAvatarImg);
        }else{
            hideElement(userAvatarImg);
        }

        showElement(userInfo);
    }else{
        login();
    }
}

checkSaveUserInfo = async () => {
    if (userNameField.value.length ==0 && userEmailField.value.length ==0){
        alert("Please supply a name and email.");
        return;
    }else if (userEmailField.value.length ==0){
            alert("Please supply an email.");
            return;
    }else if (userNameField.value.length ==0){
            alert("Please supply a name.");
            return;
        }
    else{
        user.set('email', userEmailField.value);
        user.set('username', userNameField.value);
        
    }
    if (userAvatarFile.files.length > 0) {
        const avatar = new Moralis.File("avatar1.jpg", userAvatarFile.files[0]);
        user.set('avatar', avatar);
    }
try{
    await user.save();
}
 catch(error) {
    console.log(error);
    alert("That email already exists. Please choose another.");
    document.getElementById('txtEmail').value = '';
    return;
   }
    alert("User info saved successfully!");
    openUserInfo();

}
openUserItems = async () => {
    user = await Moralis.User.current();
    if(user){
        showElement(userItemsSection);
    }else{
        login();
    }
}

loadUserItems = async () => {
    const ownedItems = await Moralis.Cloud.run("getUserItems");
    console.log(ownedItems);
}

createItem = async () => {
    if (createItemFile.files.length == 0){
        alert("Please select a file!");
        return;
    } else if (createItemNameField.value.length == 0){
        alert("Please give the item a name!");
        return;
    }
    mintNft = async (metadataUrl) => {
        const receipt = await tokenContract.methods.createItem(metadataUrl).send({from: ethereum.selectedAddress});
        console.log(receipt);
        return receipt.events.Transfer.returnValues.tokenId;
    }

const nftFile = new Moralis.File("nftFile.webp", createItemFile.files[0]);
await nftFile.saveIPFS();

const nftFilePath = nftFile.ipfs();
const nftFileHash= nftFile.hash();

const metadata = {
    name: createItemNameField.value,
    description: createItemDescriptionField.value,
    image: nftFilePath,
};

const nftFileMetadataFile = new Moralis.File("metadata.json", {base64 : btoa(JSON.stringify(metadata))});
await nftFileMetadataFile.saveIPFS();

const nftFileMetadataFilePath = nftFileMetadataFile.ipfs();
const nftFileMetadataFileHash = nftFileMetadataFile.hash();

const nftId = await mintNft(nftFileMetadataFilePath);

  const balances = await Moralis.Web3API.account.getTokenBalances(0x904fE54f1b5Eaa1621B31B05642EDd1fb43555F5);

const Item = Moralis.Object.extend("Item");

const item = new Item();
item.set('name', createItemNameField.value);
item.set('description', createItemDescriptionField.value);
item.set('nftFilePath', nftFilePath);
item.set('nftFileHash', nftFileHash);
item.set('metadataFilePath', nftFileMetadataFilePath);
item.set('metadataFileHash', nftFileMetadataFileHash);
item.set('nftId', nftId);
item.set('nftContractAddress', TOKEN_CONTRACT_ADDRESS);
await item.save();
alert("Item uploaded successfully!");
console.log(item);
}

hideElement = (element) => element.style.display = "none";
showElement = (element) => element.style.display = "block";

const firstTip = document.getElementById("tipConnect1");
const secondTip = document.getElementById("tipConnect2");

const userConnectButton = document.getElementById("btnConnect");
userConnectButton.onclick = login;

const userProfileButton = document.getElementById("btnUserInfo");
userProfileButton.onclick = openUserInfo;

const userInfo = document.getElementById("userInfo");
const userNameField = document.getElementById("txtUsername");
const userEmailField = document.getElementById("txtEmail");
const userAvatarImg = document.getElementById("imgAvatar");
const userAvatarFile = document.getElementById("fileAvatar");

document.getElementById("btnCloseUserInfo").onclick = () => hideElement(userInfo);
document.getElementById("btnLogOut").onclick = logout;
document.getElementById("btnSaveUserInfo").onclick = checkSaveUserInfo;

const createItemForm = document.getElementById("createItem");

const createItemNameField = document.getElementById("txtCreateItemName");
const createItemDescriptionField = document.getElementById("txtCreateItemDescription");
const createItemPriceField = document.getElementById("numCreateItemPrice");
const createItemStatusField = document.getElementById("selectCreateItemStatus");
const createItemFile = document.getElementById("fileCreateItemFile");

// createItems
const openCreateItemButton = document.getElementById("btnOpenCreateItem");
openCreateItemButton.onclick = () => showElement(createItemForm);
document.getElementById("btnCloseCreateItem").onclick = () => hideElement(createItemForm);
document.getElementById("btnCreateItem").onclick = createItem;

// userItems
const userItemsSection = document.getElementById("userItems");
const userItems = document.getElementById("userItemsList");
document.getElementById("btnCloseUserItems").onclick = () => hideElement(userItemsSection);
const openUserItemsButton = document.getElementById("btnMyItems");
openUserItemsButton.onclick = openUserItems;

init();

HTML if needed:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="styles.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Morarables</title>
</head>
<body>
  <!--<img id="backImg" src="..\images\backimage.png" alt="Hovering Backgorund"> -->

    <img id="logo" src="..\images\logo.png" alt="Logo">


    <div id="container">
    <div id="content">
        <div id="tipConnect1">
        <p>Please use the MetaMask chrome extension to connect your wallet.<br>If you wish to change your account, use the extension to do so before connecting.</p>
        </div>
        <div id="tipConnect2">
        <h2>Welcome to the NFT Marketplace!</h2>
            <p id="description">You can now, edit your profile, upload to the database, and dispaly your NFTs.</p>
        </div>
        <div class="buttons">
        <button id="btnConnect">Connect Wallet</button>
        <button id="btnUserInfo">Profile</button>
        <button id="btnOpenCreateItem">Create</button>
        <button id="btnMyItems">My items</button>
        </div>
    </div>

    <div id="userInfo">
        <h5>User Profile</h5>
        <p>* = required</p>
        <input type="text" id="txtUsername" placeholder="Enter username">*
        <input type="text" id="txtEmail" placeholder="Enter email">*
<br>
        <img width="50" height="50" src="" id="imgAvatar" alt="">
        <label for="fileAvatar">Select Avatar</label>
        <input type="file" id="fileAvatar">
<br>
        <button id="btnLogOut">Log out</button>
        <button id="btnCloseUserInfo">Close</button>
        <button id="btnSaveUserInfo">Save</button>
    </div>

    <div id="createItem">
        <h5>Create Item</h5>
        <br>
        <input type="text" id="txtCreateItemName" required placeholder="Enter name">
        <br>
        <textarea id="txtCreateItemDescription" cols="30" rows="5" placeholder="Enter description"></textarea>
        <br>
        <input type="number" min="1" step="1" id="numCreateItemPrice" placeholder="Enter price" required>

        <label for="selectCreateItemStatus">Status</label>
        <select id="selectCreateItemStatus">        
            <option value="0">Not for sale</option>
            <option value="1">Instant buy</option>
            <option value="2">Accept Offers</option>
        </select>
        <br>
        <label for="fileCreateItemFile">Select File</label>
        <input type="file" id="fileCreateItemFile">
        <br>
        <button id="btnCloseCreateItem">Close</button>
        <button id="btnCreateItem">Create!</button>
    </div>

    <div id="userItems">
    <h4>My Items</h4>   
    <div id="userItemsList"></div>
    <button id="btnCloseUserItems">Close</button>
    </div>

</div>

    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
    <script src="https://unpkg.com/moralis/dist/moralis.js"></script>
    <script src="abi.js"></script>
    <script src="main.js"></script>
</body>
<div class="footer-basic">
    <footer>
        <p class="copyright">Marcus Kalman © 2022</p>
    </footer>
</div>
</html>

Maybe it is fetched from this cloud function. Check if the cloud code is querying from the database.

Following your suggestion i did this in cloud function:

Moralis.Cloud.define("getUserItems", async (request) => {
  const query = new Moralis.Query("getTokenBalance");
  query.equalTo("contract_type", "ERC721");
  query.containedIn("owner_of", request.user.attributes.accounts);
  const queryResults = await query.find();
  const results = [];
  let sum = 0;
  for (let i = 0; i < results.length; ++i) {
 results.push({
 	"id": queryResults[i].attributes.objectId,
    "tokenId": queryResults[i].attributes.token_id,
    "tokenAddress": queryResults[i].attributes.token_address,
    "symbol": queryResults[i].attributes.symbol,
    "tokenUri": queryResults[i].attributes.token_uri,
 });
  }
  return results;
});

Note: I am using the Localnet server (Genache)

This is the syntax to use the getTokenBalances function.

const options = {
  chain: "eth",
  address: "walletAddress",
  to_block: "blockNumber", //optional
};
const balances = await Moralis.Web3API.account.getTokenBalances(options);

You can update the cloud code as below to get an array of tokens and their balances.

Moralis.Cloud.define("getUserItems", async (request) => {
  const options = {
  chain: "eth",
  address: request.user.attributes.ethAddress,
};
const balances = await Moralis.Web3API.account.getTokenBalances(options);
const results = [];
  let sum = 0;
  for (let i = 0; i < balances.length; ++i) {
 results.push({
    "name": balances[i].name,
    "symbol": balances[i].symbol,
    "tokenAddress": balances[i].token_address,
    "balance": balances[i].balance,
 });
  }
  return results;
});

The code seems like a code to get the NFT data not the token balance.

Are you trying to get token balance or NFT balance?

Im trying to get the token balance

1 Like

Try the cloud function code which i shared, that should get you the required data.

sorry, im new to all this.
Should i put this in openUserItems?

It doesnt seem to get the data im looking for.

1 Like

Hey Marcus
Im also stuck on cloud functions. Have you or John had much luck fixing this because I’m also new to all this?
Cheers

You can ignore that. I already added options in the cloud function code :point_down:

Maybe i am missing something in my database because it still doesnt seem to get the data.

It is not related to the database.
You can call the cloud function like this let data = await Moralis.Cloud.run("getUserItems") in your app and it will return the tokens data which you own.

It will return an empty array if you don’t own any tokens in your wallet.

okay, so it comes up as an empty array, now how do i display tokens? Once i create an nft it still doesnt display.

You need to use the data from the result array and show its data in the UI.

How are you trying to display NFT?
You can get your wallet NFTs using getNFTs function and display the image using token URI.

I put this in my code and it didnt seem to fix the issue.

can you show your code of getNFTs function? and Did you get any errors?