Can i just get someone to confirm that this is still working as it should?
I went through the steps provided and tried following the Moralis YouTube tutorial but it doesnt seem to work as expected.
Example Errors:
- Loading the main net NFT collections error:
Uncaught TypeError: setInputValue is not a function on line 228.
Line 228:onClick={() => setInputValue(nft?.addrs)}
NFTTokenIds.jsx:
import React, { useState, useEffect } from "react";
import { getNativeByChain } from "helpers/networks";
import { getCollectionsByChain } from "helpers/collections";
import {
useMoralis,
useMoralisQuery,
useNewMoralisObject,
} from "react-moralis";
import { Card, Image, Tooltip, Modal, Badge, Alert, Spin } from "antd";
import { useNFTTokenIds } from "hooks/useNFTTokenIds";
import {
FileSearchOutlined,
RightCircleOutlined,
ShoppingCartOutlined,
} from "@ant-design/icons";
import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";
import { getExplorer } from "helpers/networks";
import { useWeb3ExecuteFunction } from "react-moralis";
const { Meta } = Card;
const styles = {
NFTs: {
display: "flex",
flexWrap: "wrap",
WebkitBoxPack: "start",
justifyContent: "flex-start",
margin: "0 auto",
maxWidth: "1000px",
gap: "10px",
},
banner: {
display: "flex",
justifyContent: "space-evenly",
alignItems: "center",
margin: "0 auto",
width: "600px",
//borderRadius: "10px",
height: "150px",
marginBottom: "40px",
paddingBottom: "20px",
borderBottom: "solid 1px #e3e3e3",
},
logo: {
height: "115px",
width: "115px",
borderRadius: "50%",
// positon: "relative",
// marginTop: "-80px",
border: "solid 4px white",
},
text: {
color: "#041836",
fontSize: "27px",
fontWeight: "bold",
},
};
function NFTTokenIds({ inputValue, setInputValue }) {
const fallbackImg =
"data:image/png;base64,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";
const { NFTTokenIds, totalNFTs, fetchSuccess } = useNFTTokenIds(inputValue);
const [visible, setVisibility] = useState(false);
const [nftToBuy, setNftToBuy] = useState(null);
const [loading, setLoading] = useState(false);
const contractProcessor = useWeb3ExecuteFunction();
const { chainId, marketAddress, contractABI, walletAddress } =
useMoralisDapp();
const nativeName = getNativeByChain(chainId);
const contractABIJson = JSON.parse(contractABI);
const { Moralis } = useMoralis();
const queryMarketItems = useMoralisQuery("MarketItems");
const fetchMarketItems = JSON.parse(
JSON.stringify(queryMarketItems.data, [
"objectId",
"createdAt",
"price",
"nftContract",
"itemId",
"sold",
"tokenId",
"seller",
"owner",
"confirmed",
])
);
const purchaseItemFunction = "createMarketSale";
const NFTCollections = getCollectionsByChain(chainId);
async function purchase() {
setLoading(true);
const tokenDetails = getMarketItem(nftToBuy);
const itemID = tokenDetails.itemId;
const tokenPrice = tokenDetails.price;
const ops = {
contractAddress: marketAddress,
functionName: purchaseItemFunction,
abi: contractABIJson,
params: {
nftContract: nftToBuy.token_address,
itemId: itemID,
},
msgValue: tokenPrice,
};
await contractProcessor.fetch({
params: ops,
onSuccess: () => {
console.log("success");
setLoading(false);
setVisibility(false);
updateSoldMarketItem();
succPurchase();
},
onError: (error) => {
setLoading(false);
failPurchase();
},
});
}
const handleBuyClick = (nft) => {
setNftToBuy(nft);
console.log(nft.image);
setVisibility(true);
};
function succPurchase() {
let secondsToGo = 5;
const modal = Modal.success({
title: "Success!",
content: `You have purchased this NFT`,
});
setTimeout(() => {
modal.destroy();
}, secondsToGo * 1000);
}
function failPurchase() {
let secondsToGo = 5;
const modal = Modal.error({
title: "Error!",
content: `There was a problem when purchasing this NFT`,
});
setTimeout(() => {
modal.destroy();
}, secondsToGo * 1000);
}
async function updateSoldMarketItem() {
const id = getMarketItem(nftToBuy).objectId;
const marketList = Moralis.Object.extend("MarketItems");
const query = new Moralis.Query(marketList);
await query.get(id).then((obj) => {
obj.set("sold", true);
obj.set("owner", walletAddress);
obj.save();
});
}
const getMarketItem = (nft) => {
const result = fetchMarketItems?.find(
(e) =>
e.nftContract === nft?.token_address &&
e.tokenId === nft?.token_id &&
e.sold === false &&
e.confirmed === true
);
return result;
};
return (
<>
<div>
{contractABIJson.noContractDeployed && (
<>
<Alert
message="No Smart Contract Details Provided. Please deploy smart contract and provide address + ABI in the MoralisDappProvider.js file"
type="error"
/>
<div style={{ marginBottom: "10px" }}></div>
</>
)}
{inputValue !== "explore" && totalNFTs !== undefined && (
<>
{!fetchSuccess && (
<>
<Alert
message="Unable to fetch all NFT metadata... We are searching for a solution, please try again later!"
type="warning"
/>
<div style={{ marginBottom: "10px" }}></div>
</>
)}
<div style={styles.banner}>
<Image
preview={false}
src={NFTTokenIds[0]?.image || "error"}
fallback={fallbackImg}
alt=""
style={styles.logo}
/>
<div style={styles.text}>
<>
<div>{`${NFTTokenIds[0]?.name}`}</div>
<div
style={{
fontSize: "15px",
color: "#9c9c9c",
fontWeight: "normal",
}}
>
Collection Size: {`${totalNFTs}`}
</div>
</>
</div>
</div>
</>
)}
<div style={styles.NFTs}>
{inputValue === "explore" &&
NFTCollections?.map((nft, index) => (
<Card
hoverable
actions={[
<Tooltip title="View Collection">
<RightCircleOutlined
onClick={() => setInputValue(nft?.addrs)}
/>
</Tooltip>,
]}
style={{ width: 240, border: "2px solid #e7eaf3" }}
cover={
<Image
preview={false}
src={nft?.image || "error"}
fallback={fallbackImg}
alt=""
style={{ height: "240px" }}
/>
}
key={index}
>
<Meta title={nft.name} />
</Card>
))}
{inputValue !== "explore" &&
NFTTokenIds.slice(0, 20).map((nft, index) => (
<Card
hoverable
actions={[
<Tooltip title="View On Blockexplorer">
<FileSearchOutlined
onClick={() =>
window.open(
`${getExplorer(chainId)}address/${nft.token_address}`,
"_blank"
)
}
/>
</Tooltip>,
<Tooltip title="Buy NFT">
<ShoppingCartOutlined onClick={() => handleBuyClick(nft)} />
</Tooltip>,
]}
style={{ width: 240, border: "2px solid #e7eaf3" }}
cover={
<Image
preview={false}
src={nft.image || "error"}
fallback={fallbackImg}
alt=""
style={{ height: "240px" }}
/>
}
key={index}
>
{getMarketItem(nft) && (
<Badge.Ribbon text="Buy Now" color="green"></Badge.Ribbon>
)}
<Meta title={nft.name} description={`#${nft.token_id}`} />
</Card>
))}
</div>
{getMarketItem(nftToBuy) ? (
<Modal
title={`Buy ${nftToBuy?.name} #${nftToBuy?.token_id}`}
visible={visible}
onCancel={() => setVisibility(false)}
onOk={() => purchase()}
okText="Buy"
>
<Spin spinning={loading}>
<div
style={{
width: "250px",
margin: "auto",
}}
>
<Badge.Ribbon
color="green"
text={`${
getMarketItem(nftToBuy).price / ("1e" + 18)
} ${nativeName}`}
>
<img
src={nftToBuy?.image}
style={{
width: "250px",
borderRadius: "10px",
marginBottom: "15px",
}}
/>
</Badge.Ribbon>
</div>
</Spin>
</Modal>
) : (
<Modal
title={`Buy ${nftToBuy?.name} #${nftToBuy?.token_id}`}
visible={visible}
onCancel={() => setVisibility(false)}
onOk={() => setVisibility(false)}
>
<img
src={nftToBuy?.image}
style={{
width: "250px",
margin: "auto",
borderRadius: "10px",
marginBottom: "15px",
}}
/>
<Alert
message="This NFT is currently not for sale"
type="warning"
/>
</Modal>
)}
</div>
</>
);
}
export default NFTTokenIds;
- Listing NFTs on testnet (Ropsten) error:
Warning: Each child in a list should have a unique “key” prop.
Check the render method ofPanel
. It was passed a child from NFTBalance
NFTBalance.jsx:
import React, { useState } from "react";
import { useMoralis } from "react-moralis";
import { Card, Image, Tooltip, Modal, Input, Alert, Spin, Button } from "antd";
import { useNFTBalance } from "hooks/useNFTBalance";
import { FileSearchOutlined, ShoppingCartOutlined } from "@ant-design/icons";
import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";
import { getExplorer } from "helpers/networks";
import { useWeb3ExecuteFunction } from "react-moralis";
const { Meta } = Card;
const styles = {
NFTs: {
display: "flex",
flexWrap: "wrap",
WebkitBoxPack: "start",
justifyContent: "flex-start",
margin: "0 auto",
maxWidth: "1000px",
gap: "10px",
},
};
function NFTBalance() {
const { NFTBalance, fetchSuccess } = useNFTBalance();
const { chainId, marketAddress, contractABI } = useMoralisDapp();
const { Moralis } = useMoralis();
const [visible, setVisibility] = useState(false);
const [nftToSend, setNftToSend] = useState(null);
const [price, setPrice] = useState(1);
const [loading, setLoading] = useState(false);
const contractProcessor = useWeb3ExecuteFunction();
const contractABIJson = JSON.parse(contractABI);
const listItemFunction = "createMarketItem";
const ItemImage = Moralis.Object.extend("ItemImages");
async function list(nft, listPrice) {
setLoading(true);
const p = listPrice * ("1e" + 18);
const ops = {
contractAddress: marketAddress,
functionName: listItemFunction,
abi: contractABIJson,
params: {
nftContract: nft.token_address,
tokenId: nft.token_id,
price: String(p),
},
};
await contractProcessor.fetch({
params: ops,
onSuccess: () => {
console.log("success");
setLoading(false);
setVisibility(false);
addItemImage();
succList();
},
onError: (error) => {
setLoading(false);
failList();
},
});
}
async function approveAll(nft) {
setLoading(true);
const ops = {
contractAddress: nft.token_address,
functionName: "setApprovalForAll",
abi: [{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"}],
params: {
operator: marketAddress,
approved: true
},
};
await contractProcessor.fetch({
params: ops,
onSuccess: () => {
console.log("Approval Received");
setLoading(false);
setVisibility(false);
succApprove();
},
onError: (error) => {
setLoading(false);
failApprove();
},
});
}
const handleSellClick = (nft) => {
setNftToSend(nft);
setVisibility(true);
};
function succList() {
let secondsToGo = 5;
const modal = Modal.success({
title: "Success!",
content: `Your NFT was listed on the marketplace`,
});
setTimeout(() => {
modal.destroy();
}, secondsToGo * 1000);
}
function succApprove() {
let secondsToGo = 5;
const modal = Modal.success({
title: "Success!",
content: `Approval is now set, you may list your NFT`,
});
setTimeout(() => {
modal.destroy();
}, secondsToGo * 1000);
}
function failList() {
let secondsToGo = 5;
const modal = Modal.error({
title: "Error!",
content: `There was a problem listing your NFT`,
});
setTimeout(() => {
modal.destroy();
}, secondsToGo * 1000);
}
function failApprove() {
let secondsToGo = 5;
const modal = Modal.error({
title: "Error!",
content: `There was a problem with setting approval`,
});
setTimeout(() => {
modal.destroy();
}, secondsToGo * 1000);
}
function addItemImage() {
const itemImage = new ItemImage();
itemImage.set("image", nftToSend.image);
itemImage.set("nftContract", nftToSend.token_address);
itemImage.set("tokenId", nftToSend.token_id);
itemImage.set("name", nftToSend.name);
itemImage.save();
}
return (
<>
<div style={styles.NFTs}>
{contractABIJson.noContractDeployed && (
<>
<Alert
message="No Smart Contract Details Provided. Please deploy smart contract and provide address + ABI in the MoralisDappProvider.js file"
type="error"
/>
<div style={{ marginBottom: "10px" }}></div>
</>
)}
{!fetchSuccess && (
<>
<Alert
message="Unable to fetch all NFT metadata... We are searching for a solution, please try again later!"
type="warning"
/>
<div style={{ marginBottom: "10px" }}></div>
</>
)}
{NFTBalance &&
NFTBalance.map((nft, index) => (
<Card
hoverable
actions={[
<Tooltip title="View On Blockexplorer">
<FileSearchOutlined
onClick={() =>
window.open(
`${getExplorer(chainId)}address/${nft.token_address}`,
"_blank"
)
}
/>
</Tooltip>,
<Tooltip title="List NFT for sale">
<ShoppingCartOutlined onClick={() => handleSellClick(nft)} />
</Tooltip>,
]}
style={{ width: 240, border: "2px solid #e7eaf3" }}
cover={
<Image
preview={false}
src={nft?.image || "error"}
fallback="data:image/png;base64,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"
alt=""
style={{ height: "240px" }}
/>
}
key={index}
>
<Meta title={nft.name} description={nft.contract_type} />
</Card>
))}
</div>
<Modal
title={`List ${nftToSend?.name} #${nftToSend?.token_id} For Sale`}
visible={visible}
onCancel={() => setVisibility(false)}
onOk={() => list(nftToSend, price)}
okText="List"
footer={[
<Button onClick={() => setVisibility(false)}>
Cancel
</Button>,
<Button onClick={() => approveAll(nftToSend)} type="primary">
Approve
</Button>,
<Button onClick={() => list(nftToSend, price)} type="primary">
List
</Button>
]}
>
<Spin spinning={loading}>
<img
src={`${nftToSend?.image}`}
style={{
width: "250px",
margin: "auto",
borderRadius: "10px",
marginBottom: "15px",
}}
/>
<Input
autoFocus
placeholder="Listing Price in ETH"
onChange={(e) => setPrice(e.target.value)}
/>
</Spin>
</Modal>
</>
);
}
export default NFTBalance;
- Onload 400 error:
POST https://2xq7dhrqszhs.usemoralis.com:2053/server/functions/getAllTokenIds 400
POST https://2xq7dhrqszhs.usemoralis.com:2053/server/functions/getNativeBalance 400
useAllTokenIds.
import { useMoralisDapp } from "../providers/MoralisDappProvider/MoralisDappProvider";
import { useEffect, useState } from "react";
import { useMoralisWeb3Api, useMoralisWeb3ApiCall } from "react-moralis";
import { useIPFS } from "./useIPFS";
export const useNFTTokenIds = (addr, limit) => { //pass limit param to the hook
const { token } = useMoralisWeb3Api();
const { chainId } = useMoralisDapp();
const { resolveLink } = useIPFS();
const [NFTTokenIds, setNFTTokenIds] = useState([]);
const [totalNFTs, setTotalNFTs] = useState();
const [fetchSuccess, setFetchSuccess] = useState(true);
const {
fetch: getNFTTokenIds,
data,
error,
isLoading,
//getAllTokenIds \/
} = useMoralisWeb3ApiCall(token.getAllTokenIds, {
chain: chainId,
address: addr,
limit: limit, // use limit param here
});
useEffect(async () => {
if (data?.result) {
const NFTs = data.result;
setTotalNFTs(data.total);
setFetchSuccess(true);
for (let NFT of NFTs) {
if (NFT?.metadata) {
NFT.metadata = JSON.parse(NFT.metadata);
NFT.image = resolveLink(NFT.metadata?.image);
} else if (NFT?.token_uri) {
try {
await fetch(NFT.token_uri)
.then((response) => response.json())
.then((data) => {
NFT.image = resolveLink(data.image);
});
} catch (error) {
setFetchSuccess(false);
/* !!Temporary work around to avoid CORS issues when retrieving NFT images!!
Create a proxy server as per https://dev.to/terieyenike/how-to-create-a-proxy-server-on-heroku-5b5c
Replace <your url here> with your proxy server_url below
Remove comments :)
try {
await fetch(`<your url here>/${NFT.token_uri}`)
.then(response => response.json())
.then(data => {
NFT.image = resolveLink(data.image);
});
} catch (error) {
setFetchSuccess(false);
}
*/
}
}
}
setNFTTokenIds(NFTs);
}
}, [data]);
return {
getNFTTokenIds,
NFTTokenIds,
totalNFTs,
fetchSuccess,
error,
isLoading,
};
};
useNativeBalance.js:
import { getNativeByChain } from "helpers/networks";
import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";
import { useEffect, useMemo, useState } from "react";
import { useMoralis, useMoralisWeb3Api, useMoralisWeb3ApiCall } from "react-moralis";
export const useNativeBalance = (options) => {
const { account } = useMoralisWeb3Api();
const { Moralis } = useMoralis();
const { chainId, walletAddress } = useMoralisDapp();
const [balance, setBalance] = useState({ inWei: 0, formatted: 0 });
const nativeName = useMemo(() => getNativeByChain(options?.chain || chainId), [options, chainId]);
const {
//getBalance \/
fetch: getBalance,
data,
error,
isLoading,
} = useMoralisWeb3ApiCall(account.getNativeBalance, {
chain: chainId,
address: walletAddress,
...options,
});
useEffect(() => {
if (data?.balance) {
const balances = {
inWei: data.balance,
// missing second argument (decimals) in FromWei function,
formatted: Moralis.Units.FromWei(data.balance),
};
setBalance(balances);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
return { getBalance, balance, nativeName, error, isLoading };
};