Introduction
  
   
 What are Algorand Standard Assets (ASAs) 
  
 Algorand Stanard Assets (ASA) provide a standardized layer-1 mechanism for representing all types of assets on the Algorand Blockchain. These can include fungible, non-fungible, restricted fungible, and restricted non-fungible assets. Example asset types are :
  
     | FUNGIBLE TOKEN | NON-FUNGIBLE TOKEN | RESTRICTED FUNGIBLE TOKEN | RESTRICTED NON-FUNGIBLE TOKEN | 
  |  In-game PointsStable Coinsloyalty pointsSystem creditsCryptocurrency  |  In-game itemsSupply chainReal Estateidentity CertificationsCollectables |  SecuritiesGov's issued FiatCertifications |  Real EstateOwnership RegistriesRegulatory Certifications  | 
  
    
 What is a Non-Fungible Token(NFT)
  
 NFT is a mechanism that allows the purchaser of your products to verify what they have purchased while ensuring that what you will selling cannot be traded. It enables participants in an ecosystem to ensure what they and what value they hold will not be affected by any other user or service.
  
 It also prevents third-party players from making copies of what you are selling, which is essentially what happens in the case of digital products that can be duplicated and sold. 
  
 Non-fungible tokens represent unique digital assets. One NFT can't exchange for another, which represents the same thing in the same way. For example, one token might represent a cat, while another represents a house in monopoly.
  
 How to create NFTs
  
 We are going to create NFT using Algorand Standard Assets(ASAs), which are constructed into the protocol and created using different types of transactions. This is distinct from some other blockchains where a smart contract is necessary to represent assets. But here you just need to specify a few parameters to identify it as an NFT and link to the metadata so that potential owners have the information they need to validate the integrity of the asset. For instance, you just need to set the total amount of units you want to create for the asset to 1 and set the number of decimals to 0. This ensures you create precisely one unit of your Algorand Standard Assets(ASA) and can't divide the newly minted asset. However, you can set the number of decimals to any number according to 
ARC-0003 NFT Standard up to the protocol limit.
 
 Step 1: Set Configuration Module and the PureStake API
  
 First You need to set the Algorand module and default configurations value for the Purestake API. 
   - import json    
- import hashlib    
- import os    
- from algosdk import mnemonic    
- from algosdk.v2client import algod    
- from algosdk.future.transaction import AssetConfigTxn, wait_for_confirmation            
-             
- algod_token = 'YOUR API KEY HERE'            
- algod_address = 'https://testnet-algorand.api.purestake.io/ps2'            
- purestake_token = {'X-Api-key': algod_token}     
  Step 2: Configure your Algorand Account 
  
 Now you’ll need to recover your account using your mnemonic.
 Important Note: Mnemonics control your account. Never share them or store them insecurely. The code below is for demonstration purposes only. 
   - mnemonic_phrase = "YOUR MNEMONIC HERE";      
- account_private_key = mnemonic.to_private_key(mnemonic_phrase)      
- account_public_key = mnemonic.to_public_key(mnemonic_phrase)      
  Note- In mnemonic_phrase you need to write your Account Passphrase
  
  Checking Algorand Wallet Balance
    - account_info = algod_client.account_info(account_public_key)        
- print("Account balance: {} microAlgos".format(account_info.get('amount')))      
  Using this code you can check your Algos. And for creating NFT you have to store a minimum of 0.25 Algos. if not you can use 
Algorand Testnet Dispenser.
   
 Step 3: Create the Client
  
 To instantiate the client you need to connect PureStake API to your program.
   - algodclient = algod.AlgodClient(algod_token, algod_address, headers=purestake_token)    
   
 To get the params for the transaction before every Transaction.
   - params = algod_client.suggested_params()    
   
 After that, you need to read your JSON file where you store your NFT data 
   - {    
-     "name": "TESTNFT",    
-     "description": "ALGORAND TEST NFT",    
-     "image": "https:\/\/s3.amazonaws.com\/your-bucket\/images\/alice-nft.png",    
-     "image_integrity": "sha256-/tih/7ew0eziEZIVD4qoTWb0YrElAuRG3b40SnEstyk=",    
-     "properties": {    
-         "simple_property": "ALGORAND TEST NFT",    
-         "rich_property": {    
-             "name": "TESTNFT",    
-             "value": "001",    
-             "display_value": "001",    
-             "class": "emphasis",    
-             "css": {    
-                 "color": "#ffffff",    
-                 "font-weight": "bold",    
-                 "text-decoration": "underline"    
-             }    
-         },    
-         "array_property": {    
-             "name": "Artwork",    
-             "value": [1, 2, 3, 4],    
-             "class": "emphasis"    
-         }    
-     }    
- }    
  Change this data according to what you want, like name, description, image, value and etc. after changing the data accordingly save this data in JSON format and call this JSON in a Python file.
  
 Step 6: Read JSON file in python
  
 Now you need to read the JSON file in a python program and convert that file into sha512_256 format :
   -   
- dir_path = os.path.dirname(os.path.realpath(__file__))    
- f = open (dir_path + '/NFTData.json', "r")    
-     
-   
- metadataJSON = json.loads(f.read())    
- metadataStr = json.dumps(metadataJSON)    
-     
- hash = hashlib.new("sha512_256")    
- hash.update(b"arc0003/amj")    
- hash.update(metadataStr.encode("utf-8"))    
- json_metadata_hash = hash.digest()    
  Note- replace NFTData.json from your JSON file name
  
 Step 7: Asset Creation transaction    - txn = AssetConfigTxn(    
-       sender=account_public_key,    
-       sp=params,    
-       total=1,    
-       default_frozen=False,    
-       unit_name="TESTNFT",    
-       asset_name="Algorand Test NFT",    
-       manager=account_public_key,    
-       reserve=None,    
-       freeze=None,    
-       clawback=None,    
-       strict_empty_address_check=False,    
-       url="https://path/to/my/asset/details",     
-       metadata_hash=json_metadata_hash,    
-       decimals=0)    
    In the above code, AssetConfigTxn is a class of Algorand Python SDK where all the parameters are required for creating NFT. The parameters are :
   - sender: The account which is allocating the asset to their accounts Asset map.
- total: The total number of base units of the asset to create. This number cannot be changed.
- default_frozen: True to freeze holding for this asset by default.
- unit_name: The name of a unit of this asset. Supplied on creation. Max size is 8 bytes.
- manager: The address of the account that can manage the configuration of the asset and destroy it.
- reserve: The address of the account that holds the reserve(non-minted) units of the asset. This address has no specific authority in the protocol.
- freeze: The address of the account used to freeze the holding of this asset. If empty, freezing is not permitted.
- clawback: The address of the account that can clawback holding of this asset. If empty, clawback is not permitted.
- url: Specifies a URL where more information about the asset can be retrieved. Max size is 96 bytes.
- metadata_hash: This field is intended to be a 32-bytes hash of some metadata that is relevant to your asset and/or asset holding. the format of this metadata is up to the application.
- decimal: the number of digits to use after the decimal point when displaying the asset.\
  Step 8: Sign in the transaction and wait for transactions
  
 After assigning all the parameters you need to sign in the transaction using your private key to send the asset to Algorand Blockchain.
   -   
- try:     
-     stxn = txn.sign(account_public_key)      
-       
-       
-     txid = algod_client.send_transaction(stxn)      
-     print("Asset Creation Transaction ID: {}".format(txid))      
-       
-       
-       
-     confirmed_txn = wait_for_confirmation(algod_client, txid, 4)        
-     print("TXID: ", txid)      
-     print("Result confirmed in round: {}".format(confirmed_txn['confirmed-round']))     
- except Exception as e:      
-     print(e)    
  In the above code, we are waiting for the transaction to get submitted and verified from the testnet. I have kept it under try-except so as to catch any error or exception which may cause hindrance.
  
 You should see a response similar to the following:
   - TXID : UZCV4JQB2NJ7USKXZIG755TQMIU55BUTMFOYRD4QVYWVOT5GOWBQ      
- Waiting for confirmation    
- Result confirmed in round: 21443800    
   
 If you’d rather just drop in the code in its entirety, copy it below. You will need to enter your API key, mnemonic and other details to work properly.
   - import json      
- import hashlib      
- import os      
- from algosdk import mnemonic      
- from algosdk.v2client import algod      
- from algosdk.future.transaction import AssetConfigTxn, wait_for_confirmation              
-               
- algod_token = 'YOUR API KEY HERE'              
- algod_address = 'https://testnet-algorand.api.purestake.io/ps2'              
- purestake_token = {'X-Api-key': algod_token}     
-     
- mnemonic_phrase = "YOUR MNEMONIC HERE";        
- account_private_key = mnemonic.to_private_key(mnemonic_phrase)        
- account_public_key = mnemonic.to_public_key(mnemonic_phrase)     
-     
- account_info = algod_client.account_info(account_public_key)          
- print("Account balance: {} microAlgos".format(account_info.get('amount')))     
-     
- algodclient = algod.AlgodClient(algod_token, algod_address, headers=purestake_token)        
-     
- params = algod_client.suggested_params()      
-     
-   
- dir_path = os.path.dirname(os.path.realpath(__file__))      
- f = open (dir_path + '/NFTData.json', "r")      
-       
-   
- metadataJSON = json.loads(f.read())      
- metadataStr = json.dumps(metadataJSON)      
-       
- hash = hashlib.new("sha512_256")      
- hash.update(b"arc0003/amj")      
- hash.update(metadataStr.encode("utf-8"))      
- json_metadata_hash = hash.digest()      
-     
- txn = AssetConfigTxn(      
-       sender=account_public_key,      
-       sp=params,      
-       total=1,      
-       default_frozen=False,      
-       unit_name="TESTNFT",      
-       asset_name="Algorand Test NFT",      
-       manager=account_public_key,      
-       reserve=None,      
-       freeze=None,      
-       clawback=None,      
-       strict_empty_address_check=False,      
-       url="https://path/to/my/asset/details",       
-       metadata_hash=json_metadata_hash,      
-       decimals=0)      
-   
- try:       
-     stxn = txn.sign(account_public_key)        
-         
-       
-     txid = algod_client.send_transaction(stxn)        
-     print("Asset Creation Transaction ID: {}".format(txid))        
-         
-         
-       
-     confirmed_txn = wait_for_confirmation(algod_client, txid, 4)          
-     print("TXID: ", txid)        
-     print("Result confirmed in round: {}".format(confirmed_txn['confirmed-round']))       
- except Exception as e:        
-     print(e)      
- try:    
-     ptx = algod_client.pending_transaction_info(txid)    
-     asset_id = ptx["asset-index"]    
-     print_created_asset(algod_client, accounts[1]['pk'], asset_id)    
-     print_asset_holding(algod_client, accounts[1]['pk'], asset_id)    
- except Exception as e:    
-     print(e)    
-     
- def print_created_asset(algodclient, account, assetid):    
-   account_info = algodclient.account_info(account)    
-   idx = 0;    
-   for my_account_info in account_info['created-assets']:    
-     scrutinized_asset = account_info['created-assets'][idx]    
-     idx = idx + 1           
-     if (scrutinized_asset['index'] == assetid):    
-       print("Asset ID: {}".format(scrutinized_asset['index']))    
-       print(json.dumps(my_account_info['params'], indent=4))    
-       break    
-     
- def print_asset_holding(algodclient, account, assetid):    
-     account_info = algodclient.account_info(account)    
-     idx = 0    
-     for my_account_info in account_info['assets']:    
-         scrutinized_asset = account_info['assets'][idx]    
-         idx = idx + 1            
-         if (scrutinized_asset['asset-id'] == assetid):    
-             print("Asset ID: {}".format(scrutinized_asset['asset-id']))    
-             print(json.dumps(scrutinized_asset, indent=4))    
-             break        
  Conclusion
  
 Thank you for reading the article, hope you got to know How to mint NFT in Algorand Blockchain, and how we can use PureStake Algorand Python SDK to create a simple application.
  
 We will continue the Algorand series.