Hey Guys
I cant get the array that has the Token Uri, Token Address, Symbol, Token Id in my console.
Has anyone done the rarible clone NFT marketplace or understands how i can fix this issue with my cloud function.
Thanks in advance.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="shortcut icon" href="">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Morarables</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<link rel="stylesheet" href="main.css">
</head>
<body class="bg-dark">
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent border-bottom border-light">
<a class="navbar-brand btn btn-outline-moralis" href="#">Morarable</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<form class="mx-2 d-inline flex-md-fill">
<input type="search" class="bg-transparent border-light form-control text-light mr-sm-2 rounded-pill" placeholder="search by item or creator">
</form>
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" id="btnMyItems" href="#">My Items</a>
</li>
</ul>
<div class="d-flex">
<button class="btn btn-primary rounded-pill my-2 my-sm-0 mr-md-2" id="btnOpenCreateItem">Create</button>
<button class="btn btn-outline-moralis rounded-pill my-2 my-sm-0" id="btnConnect">Connect Wallet</button>
<button class="btn btn-outline-moralis rounded-pill my-2 my-sm-0" id="btnUserInfo">Profile</button>
</div>
</div>
</nav>
<div class="container"></div>
<div class="row row-cols-1 row-cols-md-4 mt-5" id="itemsForSale">
</div>
<div id="userInfo">
<h4>User Profile</h4>
<input type="text" id="txtUsername" required placeholder="Enter username">
<input type="text" id="txtEmail" placeholder="Enter email">
<small>Optional</small>
<img width="50" height="50" src="" id="imgAvatar" alt="">
<label for="fileAvatar">Select Avatar</label>
<input type="file" id="fileAvatar">
<button id="btnLogOut">Log out</button>
<button id="btnCloseUserInfo">Close</button>
<button id="btnSaveUserInfo">Save</button>
</div>
<div id="createItem">
<h4>Create Item</h4>
<input type="text" id="txtCreateItemName" required placeholder="Enter name">
<textarea id="txtCreateItemDescription" cols="30" rows="5" placeholder="Enter description"></textarea>
<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>
<label for="fileCreateItemFile">Select File</label>
<input type="file" id="fileCreateItemFile">
<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 id="itemTemplate">
<img src="" alt="">
<h5></h5>
<p></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script src="https://unpkg.com/moralis@latest/dist/moralis.js"></script>
<script src="main.js"></script>
<script src="abi.js"></script>
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>
</html>
Javascript
const serverUrl = "https://vxnx9mu8hh9u.usemoralis.com:2053/server";
const appId = "z75nQcm3wcoe9xd9MK8c6Lye9akXiMw1QldhfvE6";
const TOKEN_CONTRACT_ADDRESS = "0x745A9A4f0D16D12D2a29b48324B5212C314Ba9eB";
Moralis.start({ serverUrl, appId });
init = async () => {
hideElement(userItemsSection);
hideElement(userInfo);
hideElement(createItemForm);
await Moralis.enableWeb3();
web3 = new Web3(Moralis.provider);
tokenContract = new web3.eth.Contract(tokenContractAbi, TOKEN_CONTRACT_ADDRESS);
const balances = await Moralis.Web3API.account.getTokenBalances();
initUser();
loadItems();
}
initUser = async () => {
if (await Moralis.User.current()){
hideElement(userConnectButton);
showElement(userProfileButton);
showElement(openCreateItemButton);
showElement(openUserItemsButton);
}else{
showElement(userConnectButton);
hideElement(userProfileButton);
hideElement(openCreateItemButton);
hideElement(createItemForm);
hideElement(openUserItemsButton);
}
}
login = async () => {
try {
await Moralis.authenticate();
initUser();
} catch (error) {
alert(error)
}
}
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();
}
}
saveUserInfo = async () => {
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);
}
await user.save();
alert("User info saved successfully!");
openUserInfo();
}
loadUserItems = async () => {
const params = { token_address: TOKEN_CONTRACT_ADDRESS };
const ownedItems = await Moralis.Cloud.run("getUserItems", params);
console.log(ownedItems);
}
loadItems = async () => {
const items = await Moralis.Cloud.run("getItems");
user = await Moralis.User.current();
items.forEach(item => {
if (user){
if (user.attributes.accounts.includes(item.ownerOf)){
const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
if (userItemListing) userItemListing.parentNode.removeChild(userItemListing);
getAndRenderItemData(item, renderUserItem);
return;
}
}
getAndRenderItemData(item, renderItem);
});
}
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;
}
const nftFile = new Moralis.File("nftFile.jpg",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 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();
console.log(item);
}
renderUserItem = async (item) => {
const userItemListing = document.getElementById(`user-item-${item.tokenObjectId}`);
if (userItemListing) return;
const userItem = userItemTemplate.cloneNode(true);
userItem.getElementsByTagName("img")[0].src = item.image;
userItem.getElementsByTagName("img")[0].alt = item.name;
userItem.getElementsByTagName("h5")[0].innerText = item.name;
userItem.getElementsByTagName("p")[0].innerText = item.description;
userItem.getElementsByTagName("input")[0].value = item.askingPrice ?? 1;
userItem.getElementsByTagName("input")[0].disbaled = item.askingPrice > 0;
userItem.getElementsByTagName("button")[0].disbaled = item.askingPrice > 0;
userItem.getElementsByTagName("button")[0].onclick = async() => {
user = await Moralis.User.current();
if(!user){
login();
return;
}
await ensureMarketplaceIsApproved(item.tokenId, item.tokenAddress);
await marketplaceContract.methods.addItemToMarket(item.tokenId, item.tokenAddress, userItem.getElementsByTagName("input")[0].value).send({from: user.get('ethAddress') });
};
userItems.id = `user-item-${item.tokenObjectId}`
userItems.appendChild(userItem);
console.log(userItems);
}
renderItem = (item) => {
const itemForSale = marketplaceItemTemplate.cloneNode(true);
if (item.sellerAvatar){
itemForSale.getElementsByTagName("img")[0].src = item.sellerAvatar.url();
itemForSale.getElementsByTagName("img")[0].alt = item.sellerUsername;
itemForSale.getElementsByTagName("span")[0].innerText = item.sellerUsername;
}
itemForSale.getElementsByTagName("img")[0].src = item.image;
itemForSale.getElementsByTagName("img")[0].alt = item.name;
itemForSale.getElementsByTagName("h5")[0].innerText = item.name;
itemForSale.getElementsByTagName("p")[0].innerText = item.description;
itemForSale.getElementsByTagName("button")[0].innerText = `Buy for ${item.askingPrice}`;
itemForSale.getElementsByTagName("button")[0].onclick = () => buyItem(item);;
itemForSale.id = `item-${item.uid}`;
itemsForSale.appendChild(itemForSale);
}
mintNFT = async (metadataUri) => {
const receipt = await tokenContract.methods.createItem(metadataUri).send({from: ethereum.selectedAddress});;
console.log(receipt);
return receipt.events.Transfer.returnValues.tokenId;
}
hideElement = (element) => element.style.display = "none";
showElement = (element) => element.style.display = "block";
openUserItems = async () => {
user = await Moralis.User.current();
if (user){
showElement(userItemsSection);
}else{
login();
}
}
//Navbar
const userConnectButton = document.getElementById("btnConnect");
userConnectButton.onclick = login;
const userProfileButton = document.getElementById("btnUserInfo");
userProfileButton.onclick = openUserInfo;
//Userinfo
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 = saveUserInfo;
//Item Creation
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");
const openCreateItemButton = document.getElementById("btnOpenCreateItem");
openCreateItemButton.onclick = () => showElement(createItemForm);
document.getElementById("btnCloseCreateItem").onclick = () => hideElement(createItemForm);
document.getElementById("btnCreateItem").onclick = createItem;
//User Items
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();
Cloud function
Moralis.Cloud.define("getUserItems", async (request) => {
const options = { address: request.params.token_address, chain: "ropsten" };
const NFTowners = await Moralis.Web3API.token.getNFTOwners(options);
const queryResults = NFTowners.result.filter(x => x.owner_of == request.user.attributes.accounts);
const results = [];
for (let i = 0; i < queryResults.length; ++i) {
results.push({
"tokenObjectId": queryResults[i].id,
"tokenid": queryResults[i].token_id,
"tokenAddress": queryResults[i].token_address,
"symbol": queryResults[i].symbol,
"tokenUri": queryResults[i].token_uri,
});
}
return results;
});
Moralis.Cloud.define("getItems", async (request) => {
const query = new Moralis.Query("ItemsForSale");
query.notEqualTo("isSold", true);
query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");
const queryResults = await query.find({useMasterKey:true});
const results = [];
for (let i = 0; i < queryResults.length; ++i) {
if (!queryResults[i].attributes.token || !queryResults[i].attributes.user) continue;
results.push({
"uid": queryResults[i].attributes.uid,
"tokenId": queryResults[i].attributes.tokenId,
"tokenAddress": queryResults[i].attributes.tokenAddress,
"askingPrice": queryResults[i].attributes.askingPrice,
"symbol": queryResults[i].attributes.token.attributes.symbol,
"tokenUri": queryResults[i].attributes.token.attributes.token_uri,
"ownerOf": queryResults[i].attributes.token.attributes.owner_of,
"tokenObjectId": queryResults[i].attributes.token.id,
"sellerUsername": queryResults[i].attributes.user.attributes.username,
"sellerAvatar": queryResults[i].attributes.user.attributes.avatar,
});
}
return results;
});