NFT Standard: borrowNFT return reference type

So I’m having some trouble using the NonFungibleToken standard interface from the flow-nft repo:

I’ve added metadata to my NFT resource (stones.cdc), as well as a method (getRockType) that returns a string with the NFT’s “type” meta value. I can’t seem to find a way to access the metadata or methods using the NFT standard interface’s borrowNFT method though. The borrowNFT method is restricted to returning a reference to &NonFungibleToken.NFT instead of &Stones.NFT by the interface.

Should the borrowNFT method on the CollectionPublic interface from the NFT standard be able to access my metadata and methods from stones.cdc? If not, how would I access that metadata in a standard compliant way?

Stones contract:

Script that demonstrates the goal:

Thanks!

1 Like

This is an unfortunate issue with the nft standard that was discovered after the nft standard was already deployed to mainnet. It used to work because the borrowNFT method did return a reference to the type defined in the contract, but we made changes to how interface conformance was handles in cadence that made it so this returns a reference of the NonFungibleToken.NFT type, which only has the id field, and our tests did not catch it. We’d like to fix it in the interface, but we still don’t know how we can easily change the interface on chain without messing up all the contracts that implement it.

In your case, you should just ignore the borrowNFT function and write a different function that returns the whole nft reference from your contract. This is how we do it in Top Shot:

pub fun borrowMoment(id: UInt64): &TopShot.NFT? {
    if self.ownedNFTs[id] != nil {
        let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT
        return ref as! &TopShot.NFT
    } else {
        return nil
    }
} 

You create a reference as auth type, which is an authorized reference. Authorized references allow you to cast it to its base type, which we do in the return statement. Does this make sense?

2 Likes

Perfect! Thanks @flowjosh :slight_smile: