Phantom NFTs in inventory after resale: How to fix?

Hey everyone, I’m working on an NFT marketplace and I’ve run into a weird issue. I can mint, sell, and resell NFTs just fine. But after I put an NFT up for sale again, it shows up in the market but also keeps appearing in my wallet inventory on the site. It’s like a ghost NFT that won’t go away!

I’ve been scratching my head over this for a while now. Has anyone else dealt with this problem before? I’d really appreciate some help figuring out what’s going on.

Here’s a simplified version of my code for the inventory page:

async function getMyNFTs() {
  const provider = await connectWallet();
  if (!provider) return;

  const signer = provider.getSigner();
  const nftContract = getNFTContract(signer);
  const myTokens = await nftContract.getOwnedTokens();

  const nftList = [];
  for (let token of myTokens) {
    const metadata = await fetchMetadata(token.uri);
    nftList.push({
      id: token.id,
      name: metadata.name,
      image: metadata.image,
      price: token.price
    });
  }

  return nftList;
}

Any ideas on what might be causing this ghost NFT problem? Thanks in advance!

hey isaac, sounds like ur inventory isn’t updating properly after listing. maybe try adding a check for active listings before displaying NFTs? something like:

const listedNFTs = await marketContract.getListedByOwner(address);
const ownedNFTs = myTokens.filter(token => !listedNFTs.includes(token.id));

that should filter out the ghosts. lmk if it helps!

hmm, that’s an interesting problem isaac! :thinking: have you considered caching issues? sometimes browsers can be sneaky and keep old data around. maybe try clearing your cache or adding a timestamp to your inventory requests?

also, i’m curious - are you using websockets or polling to update the inventory in real-time? that could make a big difference in how quickly changes are reflected.

oh, and here’s a wild thought - what if you added a ‘status’ field to your nft objects? something like:

nftList.push({
  id: token.id,
  name: metadata.name,
  image: metadata.image,
  price: token.price,
  status: await checkNFTStatus(token.id)  // 'owned', 'listed', 'sold', etc.
});

you could filter based on that when displaying. just brainstorming here! what do you think? have you tried anything like this yet?

I’ve encountered a similar issue in my NFT marketplace project. The problem likely stems from your inventory fetching logic not accounting for active listings. When you list an NFT for sale, it’s still technically owned by you until someone buys it, which is why it’s appearing in both places.

To fix this, you’ll need to modify your getMyNFTs function to check if each token is currently listed for sale. You can do this by querying your marketplace contract to see if the token has an active listing. If it does, exclude it from the inventory display.

Here’s a rough idea of how you might adjust your code:

const activeListings = await marketplaceContract.getActiveListings(signer.address);
const nftList = myTokens.filter(token => !activeListings.includes(token.id));

This should help eliminate those phantom NFTs from your inventory while they’re listed for sale. Hope this helps!