NFT Catalog
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.
Live Site
Checkout the catalog site
Contract Addresses
NFTCatalog.cdc
: This contract contains the NFT Catalog
Network | Address |
---|---|
Mainnet | 0x49a7cda3a1eecc29 |
Testnet | 0x324c34e1c517e4db |
NFTRetrieval.cdc
: This contract contains helper functions to make it easier to discover NFTs within accounts and from the catalog
Network | Address |
---|---|
Mainnet | 0x49a7cda3a1eecc29 |
Testnet | 0x324c34e1c517e4db |
Using the Catalog (For marketplaces and other NFT applications)
All of the below examples use the catalog in mainnet, you may replace the imports to the testnet address when using the testnet network.
Example 1 - Retrieve all NFT collections on the catalog
_12import NFTCatalog from 0x49a7cda3a1eecc29_12_12/*_12 The catalog is returned as a `String: NFTCatalogMetadata`_12 The key string is intended to be a unique identifier for a specific collection._12 The NFTCatalogMetadata contains collection-level views corresponding to each_12 collection identifier._12*/_12access(all) fun main(): {String : NFTCatalog.NFTCatalogMetadata} {_12 return NFTCatalog.getCatalog()_12_12}
Example 2 - Retrieve all collection names in the catalog
_10import NFTCatalog from 0x49a7cda3a1eecc29_10_10access(all) fun main(): [String] {_10 let catalog: {String : NFTCatalog.NFTCatalogMetadata} = NFTCatalog.getCatalog()_10 let catalogNames: [String] = []_10 for collectionIdentifier in catalog.keys {_10 catalogNames.append(catalog[collectionIdentifier]!.collectionDisplay.name)_10 }_10 return catalogNames_10}
Example 3 - Retrieve NFT collections and counts owned by an account
_29import MetadataViews from 0x1d7e57aa55817448_29import NFTCatalog from 0x49a7cda3a1eecc29_29import NFTRetrieval from 0x49a7cda3a1eecc29_29_29access(all) fun main(ownerAddress: Address) : {String : Number} {_29 let catalog = NFTCatalog.getCatalog()_29 let account = getAuthAccount(ownerAddress)_29 let items : {String : Number} = {}_29_29 for key in catalog.keys {_29 let value = catalog[key]!_29 let tempPathStr = "catalog".concat(key)_29 let tempPublicPath = PublicPath(identifier: tempPathStr)!_29 account.link<&{MetadataViews.ResolverCollection}>(_29 tempPublicPath,_29 target: value.collectionData.storagePath_29 )_29 let collectionCap = account.capabilities.get<&{MetadataViews.ResolverCollection}>(tempPublicPath)_29 if !collectionCap.check() {_29 continue_29 }_29 let count = NFTRetrieval.getNFTCountFromCap(collectionIdentifier : key, collectionCap : collectionCap)_29 if count != 0 {_29 items[key] = count_29 }_29 }_29_29 return items_29}
Sample Response...
_10{_10 "schmoes_prelaunch_token": 1_10}
Example 4 - Retrieve all NFTs including metadata owned by an account
_116import MetadataViews from 0x1d7e57aa55817448_116import NFTCatalog from 0x49a7cda3a1eecc29_116import NFTRetrieval from 0x49a7cda3a1eecc29_116_116access(all) struct NFT {_116 access(all) let id : UInt64_116 access(all) let name : String_116 access(all) let description : String_116 access(all) let thumbnail : String_116 access(all) let externalURL : String_116 access(all) let storagePath : StoragePath_116 access(all) let publicPath : PublicPath_116 access(all) let privatePath: PrivatePath_116 access(all) let publicLinkedType: Type_116 access(all) let privateLinkedType: Type_116 access(all) let collectionName : String_116 access(all) let collectionDescription: String_116 access(all) let collectionSquareImage : String_116 access(all) let collectionBannerImage : String_116 access(all) let royalties: [MetadataViews.Royalty]_116_116 init(_116 id: UInt64,_116 name : String,_116 description : String,_116 thumbnail : String,_116 externalURL : String,_116 storagePath : StoragePath,_116 publicPath : PublicPath,_116 privatePath : PrivatePath,_116 publicLinkedType : Type,_116 privateLinkedType : Type,_116 collectionIdentifier: String,_116 collectionName : String,_116 collectionDescription : String,_116 collectionSquareImage : String,_116 collectionBannerImage : String,_116 royalties : [MetadataViews.Royalty]_116 ) {_116 self.id = id_116 self.name = name_116 self.description = description_116 self.thumbnail = thumbnail_116 self.externalURL = externalURL_116 self.storagePath = storagePath_116 self.publicPath = publicPath_116 self.privatePath = privatePath_116 self.publicLinkedType = publicLinkedType_116 self.privateLinkedType = privateLinkedType_116 self.collectionIdentifier = collectionIdentifier_116 self.collectionName = collectionName_116 self.collectionDescription = collectionDescription_116 self.collectionSquareImage = collectionSquareImage_116 self.collectionBannerImage = collectionBannerImage_116 self.royalties = royalties_116 }_116}_116_116access(all) fun main(ownerAddress: Address) : { String : [NFT] } {_116 let catalog = NFTCatalog.getCatalog()_116 let account = getAuthAccount<auth(Capabilities) &Account>(ownerAddress)_116 let items : [NFTRetrieval.BaseNFTViewsV1] = []_116_116 let data : {String : [NFT] } = {}_116_116 for key in catalog.keys {_116 let value = catalog[key]!_116 let tempPathStr = "catalog".concat(key)_116 let tempPublicPath = PublicPath(identifier: tempPathStr)!_116 let newCap = account.capabilities.issue<&{MetadataViews.ResolverCollection}>_116 (value.collectionData.storagePath)_116 account.capabilities.publish(newCap, tempPublicPath)_116_116 let collectionCap = account.capabilities.get<&{MetadataViews.ResolverCollection}>(tempPublicPath)_116 if !collectionCap.check() {_116 continue_116 }_116 let views = NFTRetrieval.getNFTViewsFromCap(collectionIdentifier : key, collectionCap : collectionCap)_116_116 let items : [NFT] = []_116 for view in views {_116 let displayView = view.display_116 let externalURLView = view.externalURL_116 let collectionDataView = view.collectionData_116 let collectionDisplayView = view.collectionDisplay_116 let royaltyView = view.royalties_116 if (displayView == nil || externalURLView == nil || collectionDataView == nil || collectionDisplayView == nil || royaltyView == nil) {_116 // This NFT does not have the proper views implemented. Skipping...._116 continue_116 }_116_116 items.append(_116 NFT(_116 id: view.id,_116 name : displayView!.name,_116 description : displayView!.description,_116 thumbnail : displayView!.thumbnail.uri(),_116 externalURL : externalURLView!.url,_116 storagePath : collectionDataView!.storagePath,_116 publicPath : collectionDataView!.publicPath,_116 privatePath : collectionDataView!.providerPath,_116 publicLinkedType : collectionDataView!.publicLinkedType,_116 privateLinkedType : collectionDataView!.providerLinkedType,_116 collectionIdentifier: key,_116 collectionName : collectionDisplayView!.name,_116 collectionDescription : collectionDisplayView!.description,_116 collectionSquareImage : collectionDisplayView!.squareImage.file.uri(),_116 collectionBannerImage : collectionDisplayView!.bannerImage.file.uri(),_116 royalties : royaltyView!.getRoyalties()_116 )_116 )_116 }_116 data[key] = items_116 }_116 return data_116}
Sample Response...
_23{_23 "FlovatarComponent": [],_23 "schmoes_prelaunch_token": [_23 s.aa16be98aac20e8073f923261531cbbdfae1464f570f5be796b57cdc97656248.NFT(_23 id: 1006,_23 name: "Schmoes Pre Launch Token #1006",_23 description: "",_23 thumbnail: "https://gateway.pinata.cloud/ipfs/QmXQ1iBke5wjcjYG22ACVXsCvtMJKEkwFiMf96UChP8uJq",_23 externalURL: "https://schmoes.io",_23 storagePath: /storage/SchmoesPreLaunchTokenCollection,_23 publicPath: /public/SchmoesPreLaunchTokenCollection,_23 privatePath: /private/SchmoesPreLaunchTokenCollection,_23 publicLinkedType: Type<&A.6c4fe48768523577.SchmoesPreLaunchToken.Collection{A.1d7e57aa55817448.NonFungibleToken.CollectionPublic,A. 1d7e57aa55817448.NonFungibleToken.Receiver,A.1d7e57aa55817448.MetadataViews.ResolverCollection}>(),_23 privateLinkedType: Type<&A.6c4fe48768523577.SchmoesPreLaunchToken.Collection{A.1d7e57aa55817448.NonFungibleToken.CollectionPublic,A.1d7e57aa55817448.NonFungibleToken.Provider,A.1d7e57aa55817448.MetadataViews.ResolverCollection}>(),_23 collectionName: "Schmoes Pre Launch Token",_23 collectionDescription: "",_23 collectionSquareImage: "https://gateway.pinata.cloud/ipfs/QmXQ1iBke5wjcjYG22ACVXsCvtMJKEkwFiMf96UChP8uJq",_23 collectionBannerImage: "https://gateway.pinata.cloud/ipfs/QmXQ1iBke5wjcjYG22ACVXsCvtMJKEkwFiMf96UChP8uJq",_23 royalties: []_23 )_23 ],_23 "Flovatar": []_23}
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
_32import MetadataViews from 0x1d7e57aa55817448_32import NFTCatalog from 0x49a7cda3a1eecc29_32import NFTRetrieval from 0x49a7cda3a1eecc29_32_32access(all) fun main(ownerAddress: Address) : {String : [UInt64]} {_32 let catalog = NFTCatalog.getCatalog()_32 let account = getAuthAccount<auth(Capabilities) &Account>(ownerAddress)_32_32 let items : {String : [UInt64]} = {}_32_32 for key in catalog.keys {_32 let value = catalog[key]!_32 let tempPathStr = "catalogIDs".concat(key)_32 let tempPublicPath = PublicPath(identifier: tempPathStr)!_32 let newCap = account.capabilities.issue<&{MetadataViews.ResolverCollection}>_32 (value.collectionData.storagePath)_32 account.capabilities.publish(newCap, tempPublicPath)_32_32 let collectionCap = account.capabilities.get<&{MetadataViews.ResolverCollection}>(tempPublicPath)_32 if !collectionCap.check() {_32 continue_32 }_32_32 let ids = NFTRetrieval.getNFTIDsFromCap(collectionIdentifier : key, collectionCap : collectionCap)_32_32 if ids.length > 0 {_32 items[key] = ids_32 }_32 }_32 return items_32_32}
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]
_119import MetadataViews from 0x1d7e57aa55817448_119import NFTCatalog from 0x49a7cda3a1eecc29_119import NFTRetrieval from 0x49a7cda3a1eecc29_119_119access(all) struct NFT {_119 access(all) let id : UInt64_119 access(all) let name : String_119 access(all) let description : String_119 access(all) let thumbnail : String_119 access(all) let externalURL : String_119 access(all) let storagePath : StoragePath_119 access(all) let publicPath : PublicPath_119 access(all) let privatePath: PrivatePath_119 access(all) let publicLinkedType: Type_119 access(all) let privateLinkedType: Type_119 access(all) let collectionName : String_119 access(all) let collectionDescription: String_119 access(all) let collectionSquareImage : String_119 access(all) let collectionBannerImage : String_119 access(all) let royalties: [MetadataViews.Royalty]_119_119 init(_119 id: UInt64,_119 name : String,_119 description : String,_119 thumbnail : String,_119 externalURL : String,_119 storagePath : StoragePath,_119 publicPath : PublicPath,_119 privatePath : PrivatePath,_119 publicLinkedType : Type,_119 privateLinkedType : Type,_119 collectionName : String,_119 collectionDescription : String,_119 collectionSquareImage : String,_119 collectionBannerImage : String,_119 royalties : [MetadataViews.Royalty]_119 ) {_119 self.id = id_119 self.name = name_119 self.description = description_119 self.thumbnail = thumbnail_119 self.externalURL = externalURL_119 self.storagePath = storagePath_119 self.publicPath = publicPath_119 self.privatePath = privatePath_119 self.publicLinkedType = publicLinkedType_119 self.privateLinkedType = privateLinkedType_119 self.collectionName = collectionName_119 self.collectionDescription = collectionDescription_119 self.collectionSquareImage = collectionSquareImage_119 self.collectionBannerImage = collectionBannerImage_119 self.royalties = royalties_119 }_119}_119_119access(all) fun main(ownerAddress: Address, collections: {String : [UInt64]}) : {String : [NFT] } {_119 let data : {String : [NFT] } = {}_119_119 let catalog = NFTCatalog.getCatalog()_119 let account = getAuthAccount<auth(Capabilities) &Account>(ownerAddress)_119 for collectionIdentifier in collections.keys {_119 if catalog.containsKey(collectionIdentifier) {_119 let value = catalog[collectionIdentifier]!_119 let tempPathStr = "catalog".concat(collectionIdentifier)_119 let tempPublicPath = PublicPath(identifier: tempPathStr)!_119 let newCap = account.capabilities.issue<&{MetadataViews.ResolverCollection}>_119 (value.collectionData.storagePath)_119 account.capabilities.publish(newCap, tempPublicPath)_119_119 let collectionCap = account.capabilities.get<&{MetadataViews.ResolverCollection}>(tempPublicPath)_119_119 if !collectionCap.check() {_119 return data_119 }_119_119 let views = NFTRetrieval.getNFTViewsFromIDs(collectionIdentifier : collectionIdentifier, ids: collections[collectionIdentifier]!, collectionCap : collectionCap)_119_119 let items : [NFT] = []_119_119 for view in views {_119 let displayView = view.display_119 let externalURLView = view.externalURL_119 let collectionDataView = view.collectionData_119 let collectionDisplayView = view.collectionDisplay_119 let royaltyView = view.royalties_119 if (displayView == nil || externalURLView == nil || collectionDataView == nil || collectionDisplayView == nil || royaltyView == nil) {_119 // Bad NFT. Skipping...._119 continue_119 }_119_119 items.append(_119 NFT(_119 id: view.id,_119 name : displayView!.name,_119 description : displayView!.description,_119 thumbnail : displayView!.thumbnail.uri(),_119 externalURL : externalURLView!.url,_119 storagePath : collectionDataView!.storagePath,_119 publicPath : collectionDataView!.publicPath,_119 privatePath : collectionDataView!.providerPath,_119 publicLinkedType : collectionDataView!.publicLinkedType,_119 privateLinkedType : collectionDataView!.providerLinkedType,_119 collectionName : collectionDisplayView!.name,_119 collectionDescription : collectionDisplayView!.description,_119 collectionSquareImage : collectionDisplayView!.squareImage.file.uri(),_119 collectionBannerImage : collectionDisplayView!.bannerImage.file.uri(),_119 royalties : royaltyView!.getRoyalties()_119 )_119 )_119 }_119_119 data[collectionIdentifier] = items_119 }_119 }_119_119_119 return data_119}
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.
_59import MetadataViews from 0x1d7e57aa55817448_59import NFTCatalog from 0x49a7cda3a1eecc29_59import NFTRetrieval from 0x49a7cda3a1eecc29_59_59access(all) struct NFTCollectionData {_59 access(all) let storagePath : StoragePath_59 access(all) let publicPath : PublicPath_59 access(all) let publicLinkedType: Type_59_59 init(_59 storagePath : StoragePath,_59 publicPath : PublicPath,_59 publicLinkedType : Type,_59 ) {_59 self.storagePath = storagePath_59 self.publicPath = publicPath_59 self.publicLinkedType = publicLinkedType_59 }_59}_59_59access(all) fun main(ownerAddress: Address) : { String : {String : AnyStruct} } {_59 let catalog = NFTCatalog.getCatalog()_59 let account = getAuthAccount<auth(Capabilities) &Account>(ownerAddress)_59 let items : [MetadataViews.NFTView] = []_59_59 let data : { String : {String : AnyStruct} } = {}_59_59 for key in catalog.keys {_59 let value = catalog[key]!_59 let tempPathStr = "catalog".concat(key)_59 let tempPublicPath = PublicPath(identifier: tempPathStr)!_59 let newCap = account.capabilities.issue<&{MetadataViews.ResolverCollection}>_59 (value.collectionData.storagePath)_59 account.capabilities.publish(newCap, tempPublicPath)_59 let collectionCap = account.capabilities.get<&{MetadataViews.ResolverCollection}>(tempPublicPath)_59 if !collectionCap.check() {_59 continue_59 }_59_59 var views = NFTRetrieval.getAllMetadataViewsFromCap(collectionIdentifier : key, collectionCap : collectionCap)_59_59 if views.keys.length == 0 {_59 continue_59 }_59_59 // Cadence doesn't support function return types, lets manually get rid of it_59 let nftCollectionDisplayView = views[Type<MetadataViews.NFTCollectionData>().identifier] as! MetadataViews.NFTCollectionData?_59 let collectionDataView = NFTCollectionData(_59 storagePath : nftCollectionDisplayView!.storagePath,_59 publicPath : nftCollectionDisplayView!.publicPath,_59 publicLinkedType : nftCollectionDisplayView!.publicLinkedType,_59 )_59 views.insert(key: Type<MetadataViews.NFTCollectionData>().identifier, collectionDataView)_59_59 data[key] = views_59 }_59_59 return data_59}
Example 7 - Setup a user’s account to receive a specific collection
- Run the following script to retrieve some collection-level information for an NFT collection identifier from the catalog
_58import MetadataViews from 0x1d7e57aa55817448_58import NFTCatalog from 0x49a7cda3a1eecc29_58import NFTRetrieval from 0x49a7cda3a1eecc29_58_58access(all) struct NFTCollection {_58 access(all) let storagePath : StoragePath_58 access(all) let publicPath : PublicPath_58 access(all) let privatePath: PrivatePath_58 access(all) let publicLinkedType: Type_58 access(all) let privateLinkedType: Type_58 access(all) let collectionName : String_58 access(all) let collectionDescription: String_58 access(all) let collectionSquareImage : String_58 access(all) let collectionBannerImage : String_58_58 init(_58 storagePath : StoragePath,_58 publicPath : PublicPath,_58 privatePath : PrivatePath,_58 publicLinkedType : Type,_58 privateLinkedType : Type,_58 collectionName : String,_58 collectionDescription : String,_58 collectionSquareImage : String,_58 collectionBannerImage : String_58 ) {_58 self.storagePath = storagePath_58 self.publicPath = publicPath_58 self.privatePath = privatePath_58 self.publicLinkedType = publicLinkedType_58 self.privateLinkedType = privateLinkedType_58 self.collectionName = collectionName_58 self.collectionDescription = collectionDescription_58 self.collectionSquareImage = collectionSquareImage_58 self.collectionBannerImage = collectionBannerImage_58 }_58}_58_58access(all) fun main(collectionIdentifier : String) : NFT? {_58 let catalog = NFTCatalog.getCatalog()_58_58 assert(catalog.containsKey(collectionIdentifier), message: "Invalid Collection")_58_58 return NFTCollection(_58 storagePath : collectionDataView!.storagePath,_58 publicPath : collectionDataView!.publicPath,_58 privatePath : collectionDataView!.providerPath,_58 publicLinkedType : collectionDataView!.publicLinkedType,_58 privateLinkedType : collectionDataView!.providerLinkedType,_58 collectionName : collectionDisplayView!.name,_58 collectionDescription : collectionDisplayView!.description,_58 collectionSquareImage : collectionDisplayView!.squareImage.file.uri(),_58 collectionBannerImage : collectionDisplayView!.bannerImage.file.uri()_58 )_58 }_58_58 panic("Invalid Token ID")_58}
- 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:
_28import NonFungibleToken from 0x1d7e57aa55817448_28import MetadataViews from 0x1d7e57aa55817448_28{ADDITIONAL_IMPORTS}_28_28transaction {_28_28 prepare(signer: auth(BorrowValue, IssueStorageCapabilityController, PublishCapability, SaveValue, UnpublishCapability) &Account) {_28 _28 let collectionData = {CONTRACT_NAME}.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData?_28 ?? panic("Could not resolve NFTCollectionData view. The {CONTRACT_NAME} contract needs to implement the NFTCollectionData Metadata view in order to execute this transaction")_28_28 // Return early if the account already has a collection_28 if signer.storage.borrow<&{CONTRACT_NAME}.Collection>(from: collectionData.storagePath) != nil {_28 return_28 }_28_28 // Create a new empty collection_28 let collection <- {CONTRACT_NAME}.createEmptyCollection(nftType: Type<@{CONTRACT_NAME}.NFT>())_28_28 // save it to the account_28 signer.storage.save(<-collection, to: collectionData.storagePath)_28_28 // create a public capability for the collection_28 signer.capabilities.unpublish(collectionData.publicPath)_28 let collectionCap = signer.capabilities.storage.issue<&{CONTRACT_NAME}.Collection>(collectionData.storagePath)_28 signer.capabilities.publish(collectionCap, at: collectionData.publicPath)_28 }_28}
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!
_37import "NonFungibleToken"_37import "MetadataViews"_37_37/// This transaction is what an account would run_37/// to set itself up to receive NFTs. This function_37/// uses views to know where to set up the collection_37/// in storage and to create the empty collection._37///_37/// @param contractAddress: The address of the contract that defines the token being initialized_37/// @param contractName: The name of the contract that defines the token being initialized. Ex: "ExampleNFT"_37_37transaction(contractAddress: Address, contractName: String) {_37_37 prepare(signer: auth(IssueStorageCapabilityController, PublishCapability, SaveValue) &Account) {_37 // Borrow a reference to the nft contract deployed to the passed account_37 let resolverRef = getAccount(contractAddress)_37 .contracts.borrow<&{NonFungibleToken}>(name: contractName)_37 ?? panic("Could not borrow NonFungibleToken reference to the contract. Make sure the provided contract name ("_37 .concat(contractName).concat(") and address (").concat(contractAddress.toString()).concat(") are correct!"))_37_37 // Use that reference to retrieve the NFTCollectionData view _37 let collectionData = resolverRef.resolveContractView(resourceType: nil, viewType: Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData?_37 ?? panic("Could not resolve NFTCollectionData view. The ".concat(contractName).concat(" contract needs to implement the NFTCollectionData Metadata view in order to execute this transaction"))_37_37 // Create a new empty collections_37 let emptyCollection <- collectionData.createEmptyCollection()_37_37 // save it to the account_37 signer.storage.save(<-emptyCollection, to: collectionData.storagePath)_37_37 // create a public capability for the collection_37 let collectionCap = signer.capabilities.storage.issue<&{NonFungibleToken.Collection}>(_37 collectionData.storagePath_37 )_37 signer.capabilities.publish(collectionCap, at: collectionData.publicPath)_37 }_37}
Developer Usage
1. Install the Flow CLI
2. Install Node
3. Clone the project
_10git clone --depth=1 https://github.com/onflow/nft-catalog.git
4. Install packages
- Run
npm install
in the root of the project
5. Run Test Suite
- Run
npm test
in the root of the project
Cadence Generation
Using the NFT Catalog, you can generate common scripts and transactions to be run against the Flow Blockchain to support your application.
Generate from Javascript
Installation
_10npm install @onflow/fcl_10npm install flow-catalog
or
_10yarn add @onflow/fcl_10yarn add flow-catalog
Usage
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.
_10import { getAddressMaps, scripts } from "flow-catalog";_10import * as fcl from "@onflow/fcl"_10_10const main = async () => {_10 const addressMap = await getAddressMaps();_10 console.log(await scripts.getSupportedGeneratedTransactions(addressMap));_10};_10_10main();
2. Provide a Catalog collection identifier to generate code
_15const getTemplatedTransactionCode = async function() {_15 const catalogAddressMap = await getAddressMaps()_15 const result = await cadence.scripts.genTx({_15_15 /*_15 'CollectionInitialization' is one of the available transactions from step 1._15 'Flunks' is the collection identifier in this case_15 'Flow' is a fungible token identifier (if applicable to the transaction being used)_15 */_15_15 args: ['CollectionInitialization', 'Flunks', 'flow'],_15 addressMap: catalogAddressMap_15 })_15 return result_15}
3. Use the generated code in a transaction
_10const txId = await fcl.mutate({_10 cadence: await getTemplatedTransactionCode()[0],_10 limit: 9999,_10 args: (arg: any, t: any) => []_10});_10const transaction = await fcl.tx(txId).onceSealed()_10return transaction
Generate from non-Javascript environments
Cadence scripts and transactions can be generated directly on-chain via scripts. You will need to be able to run cadence scripts to continue.
1. Retrieve a list of transactions available for code generation
Run the following script to retrieve available code generation methods: https://github.com/dapperlabs/nft-catalog/blob/main/cadence/scripts/get_supported_generated_transactions.cdc
2. Provide a catalog collection identifier to generate code
You may use the following script to generate code: https://github.com/dapperlabs/nft-catalog/blob/main/cadence/scripts/gen_tx.cdc
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.
NPM Module
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
Method signatures and their associating parameters/responses can be found in the cadence/
folder of this repo.
Scripts
_20checkForRecommendedV1Views_20genTx_20getAllNftsInAccount_20getExamplenftCollectionLength_20getExamplenftType_20getNftCatalog_20getNftCatalogProposals_20getNftCollectionsForNftType_20getNftIdsInAccount_20getNftInAccount_20getNftInAccountFromPath_20getNftMetadataForCollectionIdentifier_20getNftProposalForId_20getNftsCountInAccount_20getNftsInAccount_20getNftsInAccountFromIds_20getNftsInAccountFromPath_20getSupportedGeneratedTransactions_20hasAdminProxy_20isCatalogAdmin
Transactions
_17addToNftCatalog_17addToNftCatalogAdmin_17approveNftCatalogProposal_17mintExampleNft_17mintNonstandardNft_17proposeNftToCatalog_17rejectNftCatalogProposal_17removeFromNftCatalog_17removeNftCatalogProposal_17sendAdminCapabilityToProxy_17setupExamplenftCollection_17setupNftCatalogAdminProxy_17setupNonstandardnftCollection_17setupStorefront_17transferExamplenft_17updateNftCatalogEntry_17withdrawNftProposalFromCatalog
Installation
_10npm install flow-catalog
or
_10yarn add flow-catalog
Usage
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.
_10import { getAddressMaps, scripts } from "flow-catalog";_10_10const main = async () => {_10 const addressMap = await getAddressMaps();_10 console.log(await scripts.getNftCatalog(addressMap));_10};_10_10main();
The response of any method is a tuple-array, with the first element being the result, and the second being the error (if applicable).
For example, the result of the method above would look like -
_20[_20 {_20 BILPlayerCollection: {_20 contractName: 'Player',_20 contractAddress: '0x9e6cdb88e34fa1f3',_20 nftType: [Object],_20 collectionData: [Object],_20 collectionDisplay: [Object]_20 },_20 ..._20 SoulMadeComponent: {_20 contractName: 'SoulMadeComponent',_20 contractAddress: '0x421c19b7dc122357',_20 nftType: [Object],_20 collectionData: [Object],_20 collectionDisplay: [Object]_20 }_20 },_20 null_20]
License
The works in these files:
- FungibleToken.cdc
- NonFungibleToken.cdc
- ExampleNFT.cdc
- MetadataViews.cdc
- NFTCatalog.cdc
- NFTCatalogAdmin.cdc
- NFTRetrieval.cdc
are under the Unlicense.