Moralis.initialize("9quLXz9G6OoV6LXrakGsZQNPvCiTu9Fo5NJ0DN7y");
Moralis.serverURL = "https://sqmfav2bsl7q.moralis.io:2053/server";
const TOKEN_CONTRACT_ADDRESS = "0x34b35FdE3f6ed6130E064A3d42b966e7c714Caf7";
const MARKETPLACE_CONTRACT_ADDRESS =
"0xC34988D20271ddB0e601B6b25937E02da0AFBb7E";
//Nav bar
const userInfo = document.getElementById("userInfo");
const userConnectButton = document.getElementById("btnConnect");
const userProfileButton = document.getElementById("btnUserInfo");
//User Profile
const userUsernameField = document.getElementById("txtUsername");
const userEmailField = document.getElementById("txtEmail");
const userAvatarFile = document.getElementById("fileAvatar");
const userAvatarImg = document.getElementById("imgAvatar");
const openCreateItemButton = document.getElementById("btnOpenCreateItem");
const closeCreateItemButton = document.getElementById("btnCloseCreateItem");
const createItemForm = document.getElementById("createItem");
//Upload item
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");
init = async () => {
hideElement(userItemsSection);
hideElement(userInfo);
hideElement(createItemForm);
window.web3 = await Moralis.Web3.enable();
window.tokenContract = new web3.eth.Contract(
tokenContractAbi,
TOKEN_CONTRACT_ADDRESS
);
window.marketplaceContract = new web3.eth.Contract(
marketplaceContractAbi,
MARKETPLACE_CONTRACT_ADDRESS
);
initUser();
// loadItems();
};
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);
user = await Moralis.User.current();
const userAddress = user.get("ethAddress");
switch (createItemStatusField.value) {
case "0":
return;
case "1":
await ensureMarketplaceIsApproved(nftId, TOKEN_CONTRACT_ADDRESS);
await marketplaceContract.methods.addItemToMarket(
nftId,
TOKEN_CONTRACT_ADDRESS,
createItemPriceField.value
).send({ from: userAddress });
break;
case "2":
alert("Not yet supported");
return;
}
};
mintNft = async (metadataUrl) => {
const receipt = await tokenContract.methods
.createItem(metadataUrl)
.send({ from: ethereum.selectedAddress });
console.log(receipt);
return receipt.events.Transfer.returnValues.tokenId;
};
hideElement = (e) => {
e.style.display = "none";
};
showElement = (e) => {
e.style.display = "block";
};
initUser = async () => {
if (await Moralis.User.current()) {
hideElement(userConnectButton);
showElement(userProfileButton);
showElement(openCreateItemButton);
showElement(openUserItemsBtn);
loadUserItems();
} else {
showElement(userConnectButton);
hideElement(userProfileButton);
hideElement(openCreateItemButton);
}
};
login = async () => {
try {
await Moralis.Web3.authenticate();
initUser();
} catch (error) {
alert(error);
}
};
userConnectButton.onclick = login;
openUserInfo = async () => {
user = await Moralis.User.current();
if (user) {
const email = user.get("email");
if (email) {
userEmailField.value = email;
} else {
userEmailField.value = "";
}
userUsernameField.value = user.get("username");
const userAvatar = user.get("avatar");
if (userAvatar) {
userAvatarImg.src = userAvatar.url();
showElement(userAvatarImg);
} else {
hideElement(userAvatarImg);
}
showElement(userInfo);
} else {
login();
}
};
userProfileButton.onclick = openUserInfo;
logout = async () => {
await Moralis.User.logOut();
hideElement(userInfo);
initUser();
};
document.getElementById("btnCloseUserInfo").onclick = () =>
hideElement(userInfo);
document.getElementById("btnLogout").onclick = logout;
saveUserInfo = async () => {
user.set("email", userEmailField.value);
user.set("username", userUsernameField.value);
if (userAvatarFile.files.length > 0) {
const avatar = new Moralis.File("avatar.jpg", userAvatarFile.files[0]);
user.set("avatar", avatar);
}
await user.save();
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");
ownedItems.forEach((item) => {
getAndRenderItemData(item, renderUserItem);
});
};
// loadItems = async () => {
// const items = await Moralis.Cloud.run('getItems')
// items.forEach(item => {
// getAndRenderItemData(item, renderItem);
// })
// }
initTemplate = (id) => {
const template = document.getElementById(id);
template.id = "";
template.parentNode.removeChild(template);
return template;
};
renderUserItem = (item) => {
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;
userItems.appendChild(userItem);
};
// 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("img")[1].src = item.image;
// itemForSale.getElementsByTagName("img")[1].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.id = `item-${item.uid}`
// itemsForSale.appendChild(itemForSale);
// };
getAndRenderItemData = (item, renderFunction) => {
fetch(item.tokenUri)
.then((res) => res.json())
.then((data) => {
item.name = data.name;
item.description = data.description;
item.image = data.image;
renderFunction(item);
});
};
ensureMarketplaceIsApproved = async (tokenId, tokenAddress) => {
user = await Moralis.User.current();
const userAddress = user.get("ethAddress");
const contract = new web3.eth.Contract(tokenContractAbi, tokenAddress);
const approvedAddress = await contract.methods
.getApproved(tokenId)
.call({ from: userAddress });
if (approvedAddress != MARKETPLACE_CONTRACT_ADDRESS) {
await contract.methods.approve(MARKETPLACE_CONTRACT_ADDRESS, tokenId).send({ from: userAddress });
}
};
document.getElementById("btnCreateItem").onclick = createItem;
document.getElementById("btnSaveUserInfo").onclick = saveUserInfo;
openCreateItemButton.onclick = () => showElement(createItemForm);
closeCreateItemButton.onclick = () => hideElement(createItemForm);
//user items
const userItemsSection = document.getElementById("userItems");
const userItems = document.getElementById("userItemsList");
const openUserItemsBtn = document.getElementById("btnMyItems");
const closeUserItemsBtn = document.getElementById("btnCloseUserItems");
openUserItemsBtn.onclick = openUserItems;
closeUserItemsBtn.onclick = () => hideElement(userItemsSection);
const userItemTemplate = initTemplate("itemTemplate");
const marketplaceItemTemplate = initTemplate("marketplaceItemTemplate");
//Items for sale
const itemsForSale = document.getElementById('itemsForSale')
init();