Load the Samples/Flow SDK/x.x.x/Example NFT/Scenes/NFTExampleScene scene.
Press play and approve the transactions that come up (only on first time run)
Click Authenticate and choose the emulator_service_account.
Click Mint
Fill in the Text and URL fields and click Mint
Approve the transaction
Click List to refresh the NFT display panel and show your newly minted NFT
Repeat Mint and List as desired to make your list grow
When creating an NFT it is recommended (but not required) to implement the NonFungibleToken.INFT
interface. We will be doing so in this case.
At its simplest, an NFT on Flow is a resource with a unique id. A Collection is a resource
that will allow you to store, list, deposit, and withdraw NFTs of a specific type.
We recommend reading through the NFT tutorial
to understand what is happening, as well as reviewing the contents of Cadence/Contracts/SDKExampleNFT.cdc
The SDKExampleNFT minter allows for anyone to mint an SDKExampleNFT. Typically you would restrict
minting to an authorized account.
This tutorial will not delve deeply into the NFT contract or Cadence, instead focusing on interacting
with them using the functionality the Unity SDK provides.
//Deploy the NonFungibleToken and SDKExampleNFT contracts if they are not already deployed
StartCoroutine(DeployContracts());
}
This initializes the FlowSDK to connect to the emulator, creates and registers a DevWalletProvioder, then
starts a coroutine to deploy our contract if needed.
Contracts can be deployed via the FlowControl Tools window, but we will deploy them via code for ease
of use.
The DeployContracts coroutine:
public IEnumerator DeployContracts()
{
statusText.text = "Verifying contracts";
//Wait 1 second to ensure emulator has started up and service account information has been captured.
yield return new WaitForSeconds(1.0f);
//Get the address of the emulator_service_account, then get an account object for that account.
//We now have an Account object, which contains the contracts deployed to that account. Check if the NonFungileToken and SDKExampleNFT contracts are deployed
yield return new WaitUntil(() => txResult.IsCompleted);
//Unauthenticate as the emulator_service_account
FlowSDK.GetWalletProvider().Unauthenticate();
}
//Enable the Authenticate button.
authenticateButton.interactable = true;
statusText.text = "";
}
We start by waiting one second. This ensures that the emulator has finished initializing and
the required service account has been populated.
Next we fetch the emulator_service_account Account. This Account object will contain the contracts
that are deployed to the account. We check if both the required contracts are deployed,
and if they are not, we deploy them.
Upon first running the scene, you will be presented with two popups by DevWallet. This authorizes
the transactions that will deploy the contracts. You will not see these popups during subsequent
runs because the contracts will already be present on the account. If you purge the emulator
data, you will see the popups again the next time you play the scene.
When using Testnet or Mainnet, the NonFungibleToken contract will already be deployed at a known location.
Launching the emulator with the --contracts flag will also deploy this contract. I this case we are running
without --contracts, so we will deploy the NonFungibleToken contract ourselves.
Now that the contracts are in place, the Authenticate button will be clickable. This uses the
registered wallet provider (DevWalletProvider) to authenticate. Unless you create another account
using the FlowControl Tools panel, only emulator_service_account will be available.
After clicking Authenticate, it will prompt you to select an account to authenticate as. Choose
emulator_service_account. This is done with the following functions:
Because transactions can take a while, they are done in coroutines to prevent the interface from locking
up.
First we construct a list of arguments we are going to pass to the transaction in MintAndSave.cdc. This
list consists of a single Dictionary containing the "Text" and "URL" keys and String values from the Mint
panel. We use Cadence.Convert to convert from a Dictionary<string, string> into a Cadence {String:String}
for the argument.
The MintAndSave.cdc file contains the transaction that will be executed.
import SDKExampleNFT from 0xf8d6e0586b0a20c7
import NonFungibleToken from 0xf8d6e0586b0a20c7
transaction(md: {String:String}) {
let acct : AuthAccount
prepare(signer: AuthAccount) {
self.acct = signer
}
execute {
// Create collection if it doesn't exist
if self.acct.borrow<&SDKExampleNFT.Collection>(from: SDKExampleNFT.CollectionStoragePath) == nil
{
// Create a new empty collection
let collection <- SDKExampleNFT.createEmptyCollection()
// save it to the account
self.acct.save(<-collection, to: SDKExampleNFT.CollectionStoragePath)
This transaction checks to see if an SDKExampleNFT collection exists on the account, creating/saving/linking it if it does
not. Then it calls the contract to mint a new NFT with the desired metadata and saves it to the collection.
The List button calls the UpdateNFTPanelCoroutine function that is responsible for populating the panel with information
about the SDKExampleNFT resources in the account you are authenticated as.
public IEnumerator UpdateNFTPanelCoroutine()
{
//Create the script request. We use the text in the GetNFTsOnAccount.cdc file and pass the address of the
//authenticated account as the address of the account we want to query.
FlowScriptRequest scriptRequest = new FlowScriptRequest
{
Script = listScript.text,
Arguments = new List<CadenceBase>
{
new CadenceAddress(FlowSDK.GetWalletProvider().GetAuthenticatedAccount().Address)
}
};
//Execute the script and wait until it is completed.
This ensures that an SDKExampleNFT.Collection resource exists at the proper path, then creates and returns
a {UInt64:{String:String}} containing the information of all SDKExampleNFTs in the collection. We use
Cadence.Convert to convert this into a C# Dictionary<UInt64, Dictionary<string,string>>
After that we Instantiate prefabs to display the data of each of the returned NFTs.