98 lines
3.1 KiB
TypeScript
98 lines
3.1 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { NFTCard } from "./NFTCard";
|
|
import { useAccount } from "wagmi";
|
|
import { useScaffoldContract, useScaffoldReadContract } from "~~/hooks/scaffold-eth";
|
|
import { notification } from "~~/utils/scaffold-eth";
|
|
import { getMetadataFromIPFS } from "~~/utils/tokenization/ipfs-fetch";
|
|
import { NFTMetaData } from "~~/utils/tokenization/nftsMetadata";
|
|
|
|
export interface Collectible extends Partial<NFTMetaData> {
|
|
id: number;
|
|
uri: string;
|
|
owner: string;
|
|
}
|
|
|
|
export const MyHoldings = () => {
|
|
const { address: connectedAddress } = useAccount();
|
|
const [myAllCollectibles, setMyAllCollectibles] = useState<Collectible[]>([]);
|
|
const [allCollectiblesLoading, setAllCollectiblesLoading] = useState(false);
|
|
|
|
const { data: yourCollectibleContract } = useScaffoldContract({
|
|
contractName: "YourCollectible",
|
|
});
|
|
|
|
const { data: myTotalBalance } = useScaffoldReadContract({
|
|
contractName: "YourCollectible",
|
|
functionName: "balanceOf",
|
|
args: [connectedAddress],
|
|
watch: true,
|
|
});
|
|
|
|
useEffect(() => {
|
|
const updateMyCollectibles = async (): Promise<void> => {
|
|
if (myTotalBalance === undefined || yourCollectibleContract === undefined || connectedAddress === undefined)
|
|
return;
|
|
|
|
setAllCollectiblesLoading(true);
|
|
const collectibleUpdate: Collectible[] = [];
|
|
const totalBalance = parseInt(myTotalBalance.toString());
|
|
for (let tokenIndex = 0; tokenIndex < totalBalance; tokenIndex++) {
|
|
try {
|
|
const tokenId = await yourCollectibleContract.read.tokenOfOwnerByIndex([
|
|
connectedAddress,
|
|
BigInt(tokenIndex),
|
|
]);
|
|
|
|
const tokenURI = await yourCollectibleContract.read.tokenURI([tokenId]);
|
|
|
|
const ipfsHash = tokenURI.replace("https://ipfs.io/ipfs/", "");
|
|
|
|
const nftMetadata: NFTMetaData = await getMetadataFromIPFS(ipfsHash);
|
|
|
|
collectibleUpdate.push({
|
|
id: parseInt(tokenId.toString()),
|
|
uri: tokenURI,
|
|
owner: connectedAddress,
|
|
...nftMetadata,
|
|
});
|
|
} catch (e) {
|
|
notification.error("Error fetching all collectibles");
|
|
setAllCollectiblesLoading(false);
|
|
console.log(e);
|
|
}
|
|
}
|
|
collectibleUpdate.sort((a, b) => a.id - b.id);
|
|
setMyAllCollectibles(collectibleUpdate);
|
|
setAllCollectiblesLoading(false);
|
|
};
|
|
|
|
updateMyCollectibles();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [connectedAddress, myTotalBalance]);
|
|
|
|
if (allCollectiblesLoading)
|
|
return (
|
|
<div className="flex justify-center items-center mt-10">
|
|
<span className="loading loading-spinner loading-lg"></span>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{myAllCollectibles.length === 0 ? (
|
|
<div className="flex justify-center items-center mt-10">
|
|
<div className="text-2xl text-primary-content">No NFTs found</div>
|
|
</div>
|
|
) : (
|
|
<div className="flex flex-wrap gap-4 my-8 px-5 justify-center">
|
|
{myAllCollectibles.map(item => (
|
|
<NFTCard nft={item} key={item.id} />
|
|
))}
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
};
|