{"id":13731575,"url":"https://github.com/onflow/flow-nft","last_synced_at":"2026-04-09T19:19:21.399Z","repository":{"id":37782965,"uuid":"257024460","full_name":"onflow/flow-nft","owner":"onflow","description":"The non-fungible token standard on the Flow blockchain","archived":false,"fork":false,"pushed_at":"2025-07-28T15:23:04.000Z","size":3235,"stargazers_count":461,"open_issues_count":12,"forks_count":169,"subscribers_count":57,"default_branch":"master","last_synced_at":"2025-07-28T22:34:51.692Z","etag":null,"topics":["blockchain","linear-types","nft","onflow","smart-contracts"],"latest_commit_sha":null,"homepage":"https://onflow.org","language":"Cadence","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onflow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-19T14:45:24.000Z","updated_at":"2025-07-28T15:23:06.000Z","dependencies_parsed_at":"2023-10-20T22:11:15.143Z","dependency_job_id":"ccd0e27a-28c5-441a-b749-ad7868f5867f","html_url":"https://github.com/onflow/flow-nft","commit_stats":{"total_commits":224,"total_committers":31,"mean_commits":7.225806451612903,"dds":0.7410714285714286,"last_synced_commit":"d3bdc87a06c4bd3fa93d728792003a9208d242d6"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/onflow/flow-nft","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Fflow-nft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Fflow-nft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Fflow-nft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Fflow-nft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onflow","download_url":"https://codeload.github.com/onflow/flow-nft/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Fflow-nft/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267905319,"owners_count":24163886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","linear-types","nft","onflow","smart-contracts"],"created_at":"2024-08-03T02:01:33.295Z","updated_at":"2026-04-09T19:19:21.388Z","avatar_url":"https://github.com/onflow.png","language":"Cadence","funding_links":[],"categories":["Cadence","Others"],"sub_categories":[],"readme":"# Flow Non-Fungible Token Standard\n\nThis standard defines the minimum functionality required to\nimplement a safe, secure, and easy-to-use non-fungible token\ncontract on the [Flow blockchain](https://flow.com/)\n\n## What is Cadence?\n\n[Cadence is the resource-oriented programming language](https://cadence-lang.org/)\nfor developing smart contracts on Flow.\n\nBefore reading this standard,\nwe recommend completing the [Cadence tutorials](https://cadence-lang.org/docs/tutorial/first-steps)\nto build a basic understanding of the programming language.\n\nResource-oriented programming, and by extension Cadence,\nprovides an ideal programming model for non-fungible tokens (NFTs).\nUsers are able to store their NFT objects directly in their accounts and transact\npeer-to-peer. Learn more in this [blog post about resources](https://medium.com/dapperlabs/resource-oriented-programming-bee4d69c8f8e).\n\n## Import Addresses\n\nThe `NonFungibleToken`, `ViewResolver`, and `MetadataViews` contracts are already deployed\non various networks. You can import them in your contracts from these addresses.\nThere is no need to deploy them yourself.\n\nNote: With the emulator, you must use the -contracts flag to deploy these contracts.\n\n| Network           | Contract Address     |\n| ------------------| -------------------- |\n| Emulator/Canary   | `0xf8d6e0586b0a20c7` |\n| PreviewNet        | `0xb6763b4399a888c8` |\n| Testnet/Crescendo | `0x631e88ae7f1d7c20` |\n| Mainnet           | `0x1d7e57aa55817448` |\n\n## Core Types\n\nContracts that implement the `NonFungibleToken` interface are expected\nto utilize two resource interfaces:\n\n- `NFT` - A resource interface that describes the structure of a single NFT.\n- `Collection` - A resource interface that describes an object\n  that can hold multiple NFTs of the same type and defines ways\n  to deposit, withdraw, and query information about the stored NFTs.\n\n  Users typically store one collection per NFT type, saved at a well-known location in their account storage.\n\n  For example, all NBA Top Shot Moments owned by a single user are held in a [`TopShot.Collection`](https://github.com/dapperlabs/nba-smart-contracts/blob/master/contracts/TopShot.cdc#L605) stored in their account at the path `/storage/MomentCollection`.\n\n## Core Features\n\nThe `NonFungibleToken` contract defines the following set of functionality\nthat should be included in each implementation:\n\n### Create a new NFT collection\n\nCreate a new collection using the `Token.createEmptyCollection(nftType: Type)` function.\n\nThis function MUST return an empty collection that contains no NFTs.\n\nUsers typically save new collections to a contract-defined location in their account\nand public a capability to their collection.\n\n### Withdraw an NFT\n\nWithdraw an `NFT` from a `Collection` using the [`withdraw()`](contracts/ExampleNFT.cdc#L160) function.\nThis function emits the [`NonFungibleToken.Withdrawn`](contracts/NonFungibleToken.cdc#L78) event automatically.\n\n### Deposit an NFT\n\nDeposit an `NFT` into a `Collection` using the [`deposit()`](contracts/ExampleNFT.cdc#L169-L176) function.\nThis function emits the [`NonFungibleToken.Deposited`](contracts/NonFungibleToken.cdc#L86) event automatically.\n\n#### ⚠️ Important\n\nIn order to comply with the deposit function in the interface,\nan implementation MUST take a `@{NonFungibleToken.NFT}` resource as an argument.\nThis means that anyone can send a resource object that conforms to `{NonFungibleToken.NFT}` to a deposit function.\nIn an implementation, you MUST cast the `token` as your specific token type before depositing it or you will\ndeposit another token type into your collection. For example:\n\n```cadence\n/// `ExampleNFT` much be changed to the name of your contract\nlet token \u003c- token as! @ExampleNFT.NFT\n```\n\n### List NFTs in an account\n\nReturn a list of NFTs in a `Collection` using the [`getIDs`](contracts/ExampleNFT.cdc#L179) function.\n\n### Return the NFT type that a collection can accept in a deposit\n\nReturn types of NFTs that a `Collection` can accept in a deposit\nusing the [`getSupportedNFTTypes`](contracts/ExampleNFT.cdc#L143-L157) functions.\n\n### Get Available SubNFTs, if any\n\nSome NFTs can own other NFTs, the standard provides a [function](contracts/NonFungibleToken.cdc#L111-L131) that\nprojects can optionally implement to return information the owned NFTs.\n\n## NFT Metadata\n\nThe primary documentation for metadata views is on [the Flow developer portal](https://developers.flow.com/build/advanced-concepts/metadata-views).\nPlease refer to that for the most thorough exploration of the views with examples.\n\nNFT metadata is represented in a flexible and modular way using\nthe [standard proposed in FLIP-0636](https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md).\n\nWhen writing an NFT contract,\nyou should implement the [`MetadataViews.Resolver`](contracts/MetadataViews.cdc#L3-L6) interface,\nwhich allows your NFT to utilize one or more metadata types called views.\n\nEach view represents a different type of metadata,\nsuch as an on-chain creator biography or an off-chain video clip.\nViews do not specify or require how to store your metadata, they only specify\nthe format to query and return them, so projects can still be flexible with how they store their data.\n\n### How to read metadata\n\nThis example shows how to read basic information about an NFT\nincluding the name, description, image and owner.\n\n**Source: [get_nft_metadata.cdc](scripts/get_nft_metadata.cdc)**\n\n### How to implement metadata\n\nThe [example NFT contract](contracts/ExampleNFT.cdc) shows a basic example\nfor how to implement metadata views.\n\n### List of views\n\nThe views marked as `Core views` are considered the minimum required views to provide a full picture of any NFT. If you want your NFT to be able to be easily accessed and understood by third-party apps such as the [Flow NFT Catalog](https://nft-catalog.vercel.app/) it should implement all of them as a pre-requisite.\n\n| Name        | Purpose                                    | Status      | Source                                              | Core view\n| ----------- | ------------------------------------------ | ----------- | --------------------------------------------------- | --------------------------------------------------- |\n| `NFTView`   | Basic view that includes the name, description and thumbnail. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L32-L65)  |\n| `Display`   | Return the basic representation of an NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L85-L120)  | :white_check_mark: |\n| `HTTPFile`  | A file available at an HTTP(S) URL.        | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L143-L155)  |\n| `IPFSFile`  | A file stored in IPFS.                     | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L157-L195) |\n| `Edition`   | Return information about one or more editions for an NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L197-L229) |\n| `Editions`  | Wrapper for multiple edition views.        | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L176-L187)|\n| `Serial`    | Serial number for an NFT.                  | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L258-L270)| :white_check_mark: |\n| `Royalty`   | A Royalty Cut for a given NFT.             | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L286-L323) |\n| `Royalties` | Wrapper for multiple Royalty views.        | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L325-L352) | :white_check_mark: |\n| `Media`     | Represents a file with a corresponding mediaType | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L378-L395)|\n| `Medias`    | Wrapper for multiple Media views.          | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L397-L407)|\n| `License`   | Represents a license according to https://spdx.org/licenses/ | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L423-L432)|\n| `ExternalURL`| Exposes a URL to an NFT on an external site. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L448-L458)| :white_check_mark: |\n| `NFTCollectionData` | Provides storage and retrieval information of an NFT | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L474-L531) | :white_check_mark: |\n| `NFTCollectionDisplay` | Returns the basic representation of an NFT's Collection.  | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L547-L586) | :white_check_mark: |\n| `Rarity`   | Expose rarity information for an NFT        | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L603-L628)|\n| `Trait`    | Represents a single field of metadata on an NFT. | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L644-L671)|\n| `Traits`   | Wrapper for multiple Trait views            | Implemented | [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L673-L690)| :white_check_mark: |\n\n## How to propose a new view\n\nPlease open a issue or a pull request to propose a new metadata view\nor changes to an existing view.\n\n## Feedback\n\nWe'd love to hear from anyone who has feedback. For example:\n\n- Are there any features that are missing from the standard?\n- Are the current features defined in the best way possible?\n- Are there any pre and post conditions that are missing?\n- Are the pre and post conditions defined well enough? Error messages?\n- Are there any other actions that need an event defined for them?\n- Are the current event definitions clear enough and do they provide enough information?\n- Are there any openings for bugs or vulnerabilities that we are not noticing?\n\nPlease create an issue in this repository if there is a feature that\nyou believe needs discussing or changing.\n\n## Comparison to other standards on Ethereum\n\nThis standard covers much of the same ground as ERC-721 and ERC-1155,\nbut without most of the downsides.\n\n- Tokens cannot be sent to contracts that don't understand how to use them, because an account needs to have a `Receiver` or `Collection` in its storage to receive tokens.\n- If the recipient is a contract that has a stored `Collection`, the tokens can just be deposited to that Collection without having to do a clunky `approve`, `transferFrom`.\n- Events are defined in the contract for withdrawing and depositing, so a recipient will always be notified that someone has sent them tokens with their own deposit event.\n- This version can support batch transfers of NFTs. Even though it isn't explicitly defined in the contract, a batch transfer can be done within a transaction by just withdrawing all the tokens to transfer, then depositing them wherever they need to be, all atomically.\n- Transfers can trigger actions because users can define custom `Receivers` to execute certain code when a token is sent.\n- Easy ownership indexing: rather than iterating through all tokens to find which ones you own, you have them all stored in your account's collection and can get the list of the ones you own instantly.\n\n## How to test the standard\n\nIf you want to test out these contracts, we recommend either testing them\nwith the [Flow Playground](https://play.flow.com)\nor with the [Visual Studio Code Extension](https://github.com/onflow/flow/blob/master/docs/vscode-extension.md#cadence-visual-studio-code-extension).\n\nIf you are not making/testing any modifications to the standard contracts,\nthey are already deployed to the addresses listed above and you can just import\nfrom those directly instead of deploying them yourself.\n\nIf you want to test changes to the standards, the steps to follow are:\n\n1. Deploy `ViewResolver.cdc`\n2. Deploy `NonFungibleToken.cdc`, importing `ViewResolver`.\n3. Deploy `ExampleNFT.cdc`, importing `NonFungibleToken`.\n\nThen you can experiment with some of the other transactions and scripts in `transactions/`\nor even write your own. You'll need to replace some of the import address placeholders with addresses that you deploy to, as well as some of the transaction arguments.\n\n## Running automated tests\n\nYou can find automated tests written in the\n[Cadence testing framework](https://developers.flow.com/build/smart-contracts/testing)\nin the `tests/` directory.\nUse `flow test tests/test_example_nft.cdc` to run these tests.\n\nMore tests, written in Go, are in the `lib/go/test/` directory.\nThey use the transaction templates package that is contained in the `lib/go/templates/` directory.\nTo run the Go tests, you can run `make test` from the repository root.\nContract and transaction assets must be generated before individual tests can be run,\nso if you are wanting to run the tests individually via `go test`,\nyou must run `make generate` from within the `lib/go/` directory\nafter every revision you make to the contract or transaction files.\n\n## License\n\nThe works in these files:\n\n- [ExampleNFT.cdc](contracts/ExampleNFT.cdc)\n- [NonFungibleToken.cdc](contracts/NonFungibleToken.cdc)\n- [MetadataViews.cdc](contracts/MetadataViews.cdc)\n- [ViewResolver.cdc](contracts/ViewResolver.cdc)\n\nare under the [Unlicense](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonflow%2Fflow-nft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonflow%2Fflow-nft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonflow%2Fflow-nft/lists"}