The NFT Catalog is in the process of being deprecated.
You can still use it for existing collections in the Catalog,
but no new collections will be added from now on.
Most of the functionality that the Catalog provided is now required
and handled by default by the NonFungibleToken standard with Metadata Views.
Additionally, TokenList is a new permissionless tool that
provides some of the old aggregation functionality that NFT Catalog
provided without requiring approvals.
The NFT Catalog is an on chain registry listing NFT collections
that exists on Flow which adhere to the NFT metadata standard.
This empowers dApp developers to easily build on top of
and discover interoperable NFT collections on Flow.
Example 5 - Retrieve all NFTs including metadata owned by an account for large wallets
For Wallets that have a lot of NFTs you may run into memory issues. The common pattern to get around this for now is to retrieve just the ID's in a wallet by calling the following script
import MetadataViews from 0x1d7e57aa55817448
import NFTCatalog from 0x49a7cda3a1eecc29
import NFTRetrieval from 0x49a7cda3a1eecc29
access(all) fun main(ownerAddress: Address) : {String : [UInt64]} {
let catalog = NFTCatalog.getCatalog()
let account = getAuthAccount<auth(Capabilities) &Account>(ownerAddress)
let items : {String : [UInt64]} = {}
for key in catalog.keys {
let value = catalog[key]!
let tempPathStr = "catalogIDs".concat(key)
let tempPublicPath = PublicPath(identifier: tempPathStr)!
let newCap = account.capabilities.issue<&{MetadataViews.ResolverCollection}>
let collectionCap = account.capabilities.get<&{MetadataViews.ResolverCollection}>(tempPublicPath)
if !collectionCap.check() {
continue
}
let ids = NFTRetrieval.getNFTIDsFromCap(collectionIdentifier : key, collectionCap : collectionCap)
if ids.length > 0 {
items[key] = ids
}
}
return items
}
and then use the ids to retrieve the full metadata for only those ids by calling the following script and passing in a map of collectlionIdentifer -> [ids]
import MetadataViews from 0x1d7e57aa55817448
import NFTCatalog from 0x49a7cda3a1eecc29
import NFTRetrieval from 0x49a7cda3a1eecc29
access(all) struct NFT {
access(all) let id : UInt64
access(all) let name : String
access(all) let description : String
access(all) let thumbnail : String
access(all) let externalURL : String
access(all) let storagePath : StoragePath
access(all) let publicPath : PublicPath
access(all) let privatePath: PrivatePath
access(all) let publicLinkedType: Type
access(all) let privateLinkedType: Type
access(all) let collectionName : String
access(all) let collectionDescription: String
access(all) let collectionSquareImage : String
access(all) let collectionBannerImage : String
access(all) let royalties: [MetadataViews.Royalty]
Example 6 - Retrieve all MetadataViews for NFTs in a wallet
If you're looking for some MetadataViews that aren't in the core view list you can leverage this script to grab all the views each NFT supports. Note: You lose some typing here but get more data.
This script result can then be used to form a transaction by inserting the relevant variables from above into a transaction template like the following:
let collectionData = {CONTRACT_NAME}.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData?
?? panic("Could not resolve NFTCollectionData view. The {CONTRACT_NAME} contract needs to implement the NFTCollectionData Metadata view in order to execute this transaction")
// Return early if the account already has a collection
if signer.storage.borrow<&{CONTRACT_NAME}.Collection>(from: collectionData.storagePath) != nil {
return
}
// Create a new empty collection
let collection <- {CONTRACT_NAME}.createEmptyCollection(nftType: Type<@{CONTRACT_NAME}.NFT>())
// save it to the account
signer.storage.save(<-collection, to: collectionData.storagePath)
An even easier way to setup an account without relying
on the NFT Catalog is to just use the generic setup account transaction.
All you need is the name and address of the contract!
import "NonFungibleToken"
import "MetadataViews"
/// This transaction is what an account would run
/// to set itself up to receive NFTs. This function
/// uses views to know where to set up the collection
/// in storage and to create the empty collection.
///
/// @param contractAddress: The address of the contract that defines the token being initialized
/// @param contractName: The name of the contract that defines the token being initialized. Ex: "ExampleNFT"
?? panic("Could not borrow NonFungibleToken reference to the contract. Make sure the provided contract name ("
.concat(contractName).concat(") and address (").concat(contractAddress.toString()).concat(") are correct!"))
// Use that reference to retrieve the NFTCollectionData view
let collectionData = resolverRef.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData?
?? panic("Could not resolve NFTCollectionData view. The ".concat(contractName).concat(" contract needs to implement the NFTCollectionData Metadata view in order to execute this transaction"))
// Create a new empty collections
let emptyCollection <- collectionData.createEmptyCollection()
// save it to the account
signer.storage.save(<-emptyCollection, to: collectionData.storagePath)
// create a public capability for the collection
let collectionCap = signer.capabilities.storage.issue<&{NonFungibleToken.Collection}>(
1. Retrieve a list of transactions available for code generation:
NOTE: In order to properly bootstrap the method, you will need to run and await on the getAddressMaps() method, passing it into all of the methods as shown below.
import { getAddressMaps, scripts } from "flow-catalog";
For example, from the CLI this may be run like the following:
flow -n mainnet scripts execute ./get_tx.cdc CollectionInitialization Flunks flow
In the above example, CollectionInitialization is one of the supported transactions returned from step 1, Flunks is the name of an entry on the catalog (https://www.flow-nft-catalog.com/catalog/mainnet/Flunks), and flow is a fungible token identifier.
We exposed an interface to the catalog via a consumable NPM module. This library will expose a number of methods that can be called to interact with the catalog.
Methods can be imported as follows, all nested methods live under the scripts or transactions variable.
NOTE: In order to properly bootstrap the method, you will need to run and await on the getAddressMaps() method, passing it into all of the methods as shown below.
import { getAddressMaps, scripts } from "flow-catalog";