{"id":15771,"date":"2023-02-07T11:24:00","date_gmt":"2023-02-07T11:24:00","guid":{"rendered":"https:\/\/hederav2stg.wpenginepowered.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/"},"modified":"2025-12-08T18:46:32","modified_gmt":"2025-12-08T18:46:32","slug":"hedera-token-service-nft-token-keys-edge-cases","status":"publish","type":"post","link":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/","title":{"rendered":"Hedera Token Service: NFT Token Keys Edge Cases"},"content":{"rendered":"<div class=\"blog-video mb-40\"><iframe src=\"https:\/\/www.youtube.com\/embed\/ya3jVRwmnEk\" frameborder=\"0\" allowfullscreen loading=\"lazy\"><\/iframe><\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p dir=\"ltr\">This technical blog post tries to answer all your questions about token keys,\u00a0how to use them, and their edge cases.<\/p>\n<p dir=\"ltr\">Token keys can be set for any token created using the <a href=\"https:\/\/docs.hedera.com\/hedera\/sdks-and-apis\/hedera-api\/token-service\">Hedera Token Service (HTS)<\/a>. This means you can set token keys for both fungible and non-fungible tokens. In this blog post, we&#8217;ll focus on non-fungible tokens.<\/p>\n<p>Here\u2019s an overview of what you\u2019ll learn in this blog post:<\/p>\n<ul>\n<li><strong>Which keys can you set for tokens?<\/strong><\/li>\n<li><strong>Why do you set token keys?<\/strong><strong><\/strong><\/li>\n<li><strong>How to create an NFT using the JavaScript SDK?<\/strong><\/li>\n<li><strong>Token keys test cases<\/strong><strong><br \/><\/strong>\n<ul>\n<li><strong>Case 1:<\/strong> Can you make changes to an NFT when you don&#8217;t set an admin key?<\/li>\n<li><strong>Case 2:<\/strong> Can the admin key remove other keys?<\/li>\n<li><strong>Case 3:<\/strong> Can the admin key update other keys?<\/li>\n<li><strong>Case 4:<\/strong> Can the admin key remove itself?<\/li>\n<li><strong>Case 5:<\/strong> Can one account ID be set to different keys for the same token?<\/li>\n<li><strong>Case 6:<\/strong> Can you assign multiple accounts to a single key?<\/li>\n<li><strong>Case 7: <\/strong>Can you set no keys for an NFT?<\/li>\n<\/ul>\n<\/li>\n<li><strong>Which keys are considered high-risk for collectible NFTs?<\/strong><\/li>\n<\/ul>\n<p>Let&#8217;s start!<\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Which keys can you set for tokens?<\/h4>\n<p dir=\"ltr\">Here\u2019s an overview of the seven possible keys you can set for a token.<\/p>\n<p dir=\"ltr\">\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Admin key<\/strong>: This key can perform token update and token delete operations on the token. The admin key has the authority to change the supply key, freeze key, pause key, wipe key, and KYC key. It can also update the treasury account of the token. If empty, the token can be perceived as immutable (not able to be updated\/deleted).<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Freeze key<\/strong>: This key is used to freeze or unfreeze token accounts. When an account is frozen, it cannot perform any transactions.<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>KYC key<\/strong>: This key is used to manage the token&#8217;s KYC (Know Your Customer) information. It can be used to add, update, or remove KYC information for token accounts.<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Wipe key<\/strong>: This key is used to wipe the balance of a token account. This can be useful in cases where the account owner has lost access to the account or it has been compromised.<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Supply key<\/strong>: This key is used to manage the total supply of a token. It can be used to mint new tokens or burn existing ones. If the supply key is not set, it\u2019s not possible to mint or burn tokens.<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Pause key<\/strong>: This key has the authority to pause or unpause a token. Pausing a token prevents the token from participating in all transactions.<\/p>\n<\/li>\n<\/ul>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Fee Schedule key<\/strong>: This key can change the token&#8217;s <a href=\"https:\/\/docs.hedera.com\/hedera\/sdks-and-apis\/sdks\/tokens\/custom-token-fees\">custom fee<\/a> schedule. It must sign a <a href=\"https:\/\/docs.hedera.com\/hedera\/sdks-and-apis\/hedera-api\/token-service\/tokenfeescheduleupdate\">TokenFeeScheduleUpdate<\/a> transaction. A token without a fee schedule key is immutable, which means you can\u2019t set a custom fee schedule after the token has been created.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Why do you set token keys?<\/h4>\n<p dir=\"ltr\">When creating a token on the Hedera network, setting keys serves several important purposes.<\/p>\n<p dir=\"ltr\">\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Security<\/strong><\/p>\n<\/li>\n<\/ul>\n<p dir=\"ltr\">Setting different keys for different functions ensures that only authorized individuals or entities have control over specific actions related to the token. For example, only the admin key holder can update the token&#8217;s properties, only the treasury key holder can transfer funds from the token&#8217;s treasury account, etc.<\/p>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Flexibility<\/strong><\/p>\n<\/li>\n<\/ul>\n<p dir=\"ltr\">Setting multiple keys for the same function allows for multiple individuals or entities to perform that function, providing redundancy and fail-safes.<\/p>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Transparency<\/strong><\/p>\n<\/li>\n<\/ul>\n<p dir=\"ltr\">Setting different keys for different functions also provides transparency and accountability to the token holders and other stakeholders. They can see who has the power to perform certain actions and can hold them accountable for their actions.<\/p>\n<ul>\n<li dir=\"ltr\">\n<p dir=\"ltr\"><strong>Compliance<\/strong><\/p>\n<\/li>\n<\/ul>\n<p dir=\"ltr\">Setting different keys for different functions also allows for compliance with regulatory requirements. For example, setting a KYC key allows for the token issuer to comply with know-your-customer regulations and setting a freeze key allows for freezing of accounts that are suspected of engaging in illegal activities.<\/p>\n<p><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">How to create an NFT using the JavaScript SDK?<\/h4>\n<p>Here&#8217;s an example of how you can create an NFT with the Hedara Token Service using the Hedera JavaScript SDK, setting all token keys.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let nftCreate = await new TokenCreateTransaction()\n    .setTokenName(\"Fall Collection\")\n    .setTokenSymbol(\"LEAF\")\n    .setTokenType(TokenType.NonFungibleUnique)\n    .setDecimals(0)\n    .setInitialSupply(0)\n    .setTreasuryAccountId(treasuryId) \/\/ needs to sign\n    .setSupplyType(TokenSupplyType.Finite)\n    .setMaxSupply(5)\n    \/\/ Set keys\n    .setAdminKey(adminKey)\n    .setFreezeKey(randomKey)\n    .setKycKey(randomKey)\n    .setWipeKey(randomKey)\n    .setSupplyKey(randomKey)\n    .setPauseKey(randomKey)\n    .setFeeScheduleKey(randomKey)\n    .freezeWith(client);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p dir=\"auto\">Now, let&#8217;s take a look at specific test cases related to setting token keys.<\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Token keys test cases<\/h4>\n<p>In this section, you&#8217;ll learn about seven test cases related to setting token keys for NFTs.<\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 1:\u00a0Can you make changes to an NFT when you don&#8217;t set an admin key?<\/h4>\n<p><strong>Output:<\/strong> The token becomes immutable when you don&#8217;t set an admin key. This means that none of the token properties can be updated.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let nftCreateTx = await new TokenCreateTransaction()\n    .setTokenName(\"Fall Collection\")\n    .setTokenSymbol(\"LEAF\")\n    .setTokenType(TokenType.NonFungibleUnique)\n    .setDecimals(0)\n    .setInitialSupply(0)\n    .setTreasuryAccountId(treasuryId)\n    .setSupplyType(TokenSupplyType.Finite)\n    .setMaxSupply(5)\n    \/\/ No admin key, only the required supply key is set\n    .setSupplyKey(treasuryKey)\n    .freezeWith(client)\n    .sign(treasuryKey);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong><a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/immutable-token.js\" target=\"_blank\"> immutable-token.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 2:\u00a0Can the admin key remove other keys or itself?<\/h4>\n<p><strong>Output:<\/strong> No, it&#8217;s not possible to remove keys or itself. The admin key is only allowed to update keys. When you set a key to &#8220;null&#8221; or &#8220;undefined&#8221;, nothing will change.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let tokenUpdateTx = await new TokenUpdateTransaction()\n    .setTokenId(tokenId)\n    .setSupplyKey(null) \/\/ if you set this to null, nothing happens\n    .freezeWith(client)\n    .sign(adminKey);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong> <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/all-keys-remove-supply.js\" target=\"_blank\">all-keys-remove-supply.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 3:\u00a0Can the admin key update other keys?<\/h4>\n<p><strong>Output:<\/strong> Yes, the admin key has the authority to change the supply key, freeze key, pause key, wipe key, and KYC key. Note that the updated key doesn&#8217;t need to sign the transaction for it to be assigned to a specific key for the token.<\/p>\n<p>In the example below, the supply key is updated with a new supply key. The &#8220;newSupplyKey&#8221; doesn&#8217;t need to sign the transaction. Only the &#8220;adminKey&#8221; needs to sign.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let tokenUpdateTx = await new TokenUpdateTransaction()\n    .setTokenId(tokenId)\n    .setSupplyKey(newSupplyKey) \n    .freezeWith(client)\n    .sign(adminKey);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong> <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/all-keys-update-supply.js\" target=\"_blank\">all-keys-update-supply.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 4:\u00a0Can the admin key be updated to a new admin key?<\/h4>\n<p><strong>Output:<\/strong> Yes, the admin key can be updated when it&#8217;s set. Both the old and the new admin key must sign the transaction to be successful.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let tokenUpdateTx = await new TokenUpdateTransaction()\n    .setTokenId(tokenId)\n    .setAdminKey(newAdminKey)\n    .freezeWith(client)\n    .sign(newAdminKey);\n\nlet tokenUpdateTxSign = await tokenUpdateTx.sign(adminKey);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong> <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/token-update-admin-key.js\" target=\"_blank\">token-update-admin-key.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 5:\u00a0Can one account ID be set to different keys for the same token?<\/h4>\n<p><strong>Output:<\/strong> Yes, you are allowed to set the same account for multiple keys on a token. For instance, our base example uses the &#8220;random account ID&#8221; for 6 keys.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let nftCreate = await new TokenCreateTransaction()\n    .setTokenName(\"Fall Collection\")\n    .setTokenSymbol(\"LEAF\")\n    .setTokenType(TokenType.NonFungibleUnique)\n    .setDecimals(0)\n    .setInitialSupply(0)\n    .setTreasuryAccountId(treasuryId)\n    .setSupplyType(TokenSupplyType.Finite)\n    .setMaxSupply(5)\n    \/\/ Set keys\n    .setAdminKey(adminKey)\n    .setFreezeKey(randomKey) \/\/ 1\n    .setKycKey(randomKey) \/\/ 2\n    .setWipeKey(randomKey) \/\/ 3\n    .setSupplyKey(randomKey) \/\/ 4\n    .setPauseKey(randomKey) \/\/ 5\n    .setFeeScheduleKey(randomKey) \/\/ 6\n    .freezeWith(client);\n\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong> <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/all-keys.js\" target=\"_blank\">all-keys.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 6:\u00a0Can you assign multiple accounts to a single key?<\/h4>\n<p><strong>Output:<\/strong> Yes, you can create a <em>KeyList<\/em>, which acts as a multisig. For instance, you can create a <em>KeyList<\/em> that contains two accounts and set the signing requirements to 2-out-of-2. Both accounts need to sign when the specific key is required.<\/p>\n<p>Below you will find an example with an admin key that has been assigned a 2-out-of-2 <em>KeyList<\/em>.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">\/\/ Create keylist\nconsole.log(`- Generating keylist...`);\nconst keyList = new KeyList([key1.publicKey, key2.publicKey], 2); \/\/ 2-out-of-2\n\n\/\/ Create NFT\nconsole.log(`n- Creating NFT`);\nlet nftCreate = await new TokenCreateTransaction()\n    .setNodeAccountIds(nodeId)\n    .setTokenName(\"Fall Collection\")\n    .setTokenSymbol(\"LEAF\")\n    .setTokenType(TokenType.NonFungibleUnique)\n    .setDecimals(0)\n    .setInitialSupply(0)\n    .setTreasuryAccountId(treasuryId) \/\/ needs to sign\n    .setSupplyType(TokenSupplyType.Finite)\n    .setMaxSupply(5)\n    \/\/ Set keys\n    .setAdminKey(keyList) \/\/ multisig (keylist)\n    .setSupplyKey(randomKey)\n    .freezeWith(client)\n    .sign(treasuryKey);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p>When you want to execute a transaction, both keys need to sign.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">\/\/ Adding multisig signatures\nconst sig1 = key1.signTransaction(nftCreate);\nconst sig2 = key2.signTransaction(nftCreate);\nconst nftCreateTxSign = nftCreate.addSignature(key1.publicKey, sig1).addSignature(key2.publicKey, sig2);\n\nlet nftCreateSubmit = await nftCreateTxSign.execute(client);\nlet nftCreateRx = await nftCreateSubmit.getReceipt(client);\nlet tokenId = nftCreateRx.tokenId;\nconsole.log(`- Created NFT with Token ID: ${tokenId}`);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong> <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/token-admin-keylist.js\" target=\"_blank\">token-admin-keylist.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Case 7:\u00a0Can you set no keys for an NFT?<\/h4>\n<p><strong>Output:<\/strong> No, the supply key is the only required key when you don&#8217;t set any other keys for an NFT. If you don&#8217;t set a supply key, you get the error &#8220;TOKEN_HAS_NO_SUPPLY_KEY&#8221;.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">let nftCreate = await new TokenCreateTransaction()\n    .setTokenName(\"Fall Collection\")\n    .setTokenSymbol(\"LEAF\")\n    .setTokenType(TokenType.NonFungibleUnique)\n    .setDecimals(0)\n    .setInitialSupply(0)\n    .setTreasuryAccountId(treasuryId) \/\/ needs to sign\n    .setSupplyType(TokenSupplyType.Finite)\n    .setMaxSupply(5)\n    \/\/ No keys throws error: TOKEN_HAS_NO_SUPPLY_KEY\n    .setSupplyKey(randomKey) \/\/ REQUIRED\n    .freezeWith(client);\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p><strong>Code example:<\/strong> <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\/blob\/main\/no-keys.js\" target=\"_blank\">no-keys.js<\/a><\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Which keys are considered high-risk for collectible NFTs?<\/h4>\n<p>This blog post section explores the different risk scores associated with setting specific keys for non-fungible tokens. Each key receives a relative score and a risk level based on the actions it can carry out. The below risk information is only applicable to NFT collections.\u00a0<\/p>\n<p>This section aims to educate NFT creators on which keys to set for their NFT collection and to help them understand the implications.<\/p>\n<p>Here&#8217;s an overview of all keys, their risk score, and why they got this score.<\/p>\n<ul>\n<li><strong>Admin key [score: 200 &#8211; HIGH]:\u00a0<\/strong>This key can update token properties and\u00a0change other keys for the NFT. Therefore, it could create a new account and update a specific key for the NFT to the newly created account it owns. Besides that, the admin key can delete an NFT\u00a0forever.\u00a0<\/li>\n<li><strong>Wipe key [score: 200 &#8211; HIGH]:\u00a0<\/strong>The wipe key has received an equal risk score of 200 because it can wipe the NFT\u00a0balance of an account. This key is often set as a backup mechanism when a user loses access to their account, or it&#8217;s corrupted. The wipe key can remove the account balance of the affected account, and the user can then make a new account and receive the token again. However, this key can also wipe the account balance of users that didn&#8217;t request this.<\/li>\n<li><strong>Freeze key [score: 50 &#8211; MEDIUM]:<\/strong>\u00a0When the freeze key freezes an account, this account can&#8217;t make any transactions using the specific NFT. In short, the freeze key can exclude someone from using the NFT.<\/li>\n<li><strong>KYC key [score: 50 &#8211; MEDIUM]:\u00a0<\/strong>The KYC key can grant or revoke KYC of an account for the NFT&#8217;s transactions when set. When the KYC for an account is revoked, it&#8217;s impossible to use the NFT in transactions.<\/li>\n<li><strong>Pause key [score: 50 &#8211; MEDIUM]:<\/strong>\u00a0The pause key can pause the entire NFT collection. It means that nobody can use any NFT in transactions.\u00a0<\/li>\n<li><strong>Fee schedule key [score: 40 &#8211; LOW]:\u00a0<\/strong>The fee schedule key can change the fee users pay when they trade an NFT. The key only received a low risk score because the maximum fee that can be set is 100%. So, a user trading an NFT for 10 Hbar will pay an additional 10\u00a0Hbar fee to the treasury account. It&#8217;s not a big exploit, but one to consider.<\/li>\n<li><strong>Supply key: [score: 20 &#8211; LOW]:<\/strong>\u00a0When the supply type is set to &#8220;INFINITE&#8221;, the supply key can mint as many NFTs for a collection as they want. This means the supply key can dilute an NFT project. The risk is eliminated when the supply type is set to FINITE because there&#8217;s a fixed limit for the number of NFTs this key can mint.<\/li>\n<\/ul>\n<p><strong>Note:<\/strong> When someone buys an NFT from an NFT collection, they want to ensure that nobody can tamper with the NFT itself. Therefore, most projects set no keys, making the NFT immutable. This results in a zero risk score.\u00a0<\/p>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<p>If you want to automate the process of calculating risk levels for NFTs, you can use the Hedera\u00a0NFT Utilities SDK to automate this task. The <a href=\"https:\/\/github.com\/hashgraph\/hedera-nft-utilities#risk-score-calculation\" target=\"_blank\">risk score calculation section<\/a> shows you how to use this functionality and what output you can expect. Here&#8217;s a quick example.<\/p>\n<\/div>\n<div class=\"hedera-code-window\" style=\"background-image:url('https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg');padding:24px;border-radius:8px;margin:24px 0;\">\n<p>  <!-- Hidden image so WP All Import downloads this background image into Media Library --><br \/>\n  <img decoding=\"async\" src=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/CodeSnippetBackground-scaled.jpg\" alt=\"code window background\" style=\"display:none;\" \/><\/p>\n<div class=\"code-window-header\">\n<div class=\"code-window-title\"><\/div>\n<div class=\"code-window-body\"><\/div>\n<\/p><\/div>\n<pre><code class=\"language-javascript\">const { calculateRiskScoreFromData } = require('@hashgraph\/nft-utilities');\n\nconst tokenInformation = {\n        \"admin_key\": null,\n        \"auto_renew_account\": \"0.0.784037\", \"auto_renew_period\": 7776000,\n        \"freeze_key\": null,\n        ...\n}\n\nconst results = calculateRiskScoreFromData(tokenInformation);\n\n\/* Output:\n * { \"riskScore\": \"0\", \"riskLevel\": \"NORISK\" }\n *\/\n<\/code><\/pre>\n<\/div>\n<div class=\"body-text BodyCopy mb-40 style-1\">\n<h4 class=\"color-ultraviolet\">Learn more about token keys?<\/h4>\n<p>\u2753 Reach out on <a href=\"https:\/\/hedera.com\/discord\" target=\"_blank\">Discord<\/a> or look at the docs about <a href=\"https:\/\/docs.hedera.com\/hedera\/sdks-and-apis\/sdks\/tokens\/define-a-token\" target=\"_blank\">token creation<\/a> using the Hedera Token Service.<\/p>\n<p>  If you want to explore all examples, check the <a href=\"https:\/\/github.com\/michielmulders\/token-keys-test-cases\" target=\"_blank\">token keys example repository<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Learn more about the possibilities of token keys and their edge cases. In this blog post, you&#8217;ll find technical examples showing you what token keys can do.<\/p>\n","protected":false},"author":10,"featured_media":16882,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[1],"tags":[45],"ppma_author":[43],"class_list":["post-15771","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-technical"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Hedera Token Service: NFT Token Keys Edge Cases | Hedera<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hedera Token Service: NFT Token Keys Edge Cases | Hedera\" \/>\n<meta property=\"og:description\" content=\"Learn more about the possibilities of token keys and their edge cases. In this blog post, you&#039;ll find technical examples showing you what token keys can do.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\" \/>\n<meta property=\"og:site_name\" content=\"Hedera\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-07T11:24:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-08T18:46:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"670\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Hedera Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\"},\"author\":{\"name\":\"Hedera Team\",\"@id\":\"https:\/\/hedera.com\/#\/schema\/person\/2dc6146f9f20a44d3de58c834d52e9f4\"},\"headline\":\"Hedera Token Service: NFT Token Keys Edge Cases\",\"datePublished\":\"2023-02-07T11:24:00+00:00\",\"dateModified\":\"2025-12-08T18:46:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\"},\"wordCount\":1699,\"publisher\":{\"@id\":\"https:\/\/hedera.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png\",\"keywords\":[\"technical\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\",\"url\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\",\"name\":\"Hedera Token Service: NFT Token Keys Edge Cases | Hedera\",\"isPartOf\":{\"@id\":\"https:\/\/hedera.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png\",\"datePublished\":\"2023-02-07T11:24:00+00:00\",\"dateModified\":\"2025-12-08T18:46:32+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage\",\"url\":\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png\",\"contentUrl\":\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png\",\"width\":1200,\"height\":670},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/hedera.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hedera Token Service: NFT Token Keys Edge Cases\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/hedera.com\/#website\",\"url\":\"https:\/\/hedera.com\/\",\"name\":\"Hedera\",\"description\":\"Hello future\",\"publisher\":{\"@id\":\"https:\/\/hedera.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/hedera.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/hedera.com\/#organization\",\"name\":\"Hedera\",\"url\":\"https:\/\/hedera.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/hedera.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/09\/hedera_logo.png\",\"contentUrl\":\"https:\/\/hedera.com\/wp-content\/uploads\/2025\/09\/hedera_logo.png\",\"width\":500,\"height\":375,\"caption\":\"Hedera\"},\"image\":{\"@id\":\"https:\/\/hedera.com\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Hedera Token Service: NFT Token Keys Edge Cases | Hedera","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/","og_locale":"en_US","og_type":"article","og_title":"Hedera Token Service: NFT Token Keys Edge Cases | Hedera","og_description":"Learn more about the possibilities of token keys and their edge cases. In this blog post, you'll find technical examples showing you what token keys can do.","og_url":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/","og_site_name":"Hedera","article_published_time":"2023-02-07T11:24:00+00:00","article_modified_time":"2025-12-08T18:46:32+00:00","og_image":[{"width":1200,"height":670,"url":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png","type":"image\/png"}],"author":"Hedera Team","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#article","isPartOf":{"@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/"},"author":{"name":"Hedera Team","@id":"https:\/\/hedera.com\/#\/schema\/person\/2dc6146f9f20a44d3de58c834d52e9f4"},"headline":"Hedera Token Service: NFT Token Keys Edge Cases","datePublished":"2023-02-07T11:24:00+00:00","dateModified":"2025-12-08T18:46:32+00:00","mainEntityOfPage":{"@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/"},"wordCount":1699,"publisher":{"@id":"https:\/\/hedera.com\/#organization"},"image":{"@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage"},"thumbnailUrl":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png","keywords":["technical"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/","url":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/","name":"Hedera Token Service: NFT Token Keys Edge Cases | Hedera","isPartOf":{"@id":"https:\/\/hedera.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage"},"image":{"@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage"},"thumbnailUrl":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png","datePublished":"2023-02-07T11:24:00+00:00","dateModified":"2025-12-08T18:46:32+00:00","breadcrumb":{"@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#primaryimage","url":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png","contentUrl":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner.png","width":1200,"height":670},{"@type":"BreadcrumbList","@id":"https:\/\/hedera.com\/blog\/hedera-token-service-nft-token-keys-edge-cases\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hedera.com\/"},{"@type":"ListItem","position":2,"name":"Hedera Token Service: NFT Token Keys Edge Cases"}]},{"@type":"WebSite","@id":"https:\/\/hedera.com\/#website","url":"https:\/\/hedera.com\/","name":"Hedera","description":"Hello future","publisher":{"@id":"https:\/\/hedera.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hedera.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/hedera.com\/#organization","name":"Hedera","url":"https:\/\/hedera.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hedera.com\/#\/schema\/logo\/image\/","url":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/09\/hedera_logo.png","contentUrl":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/09\/hedera_logo.png","width":500,"height":375,"caption":"Hedera"},"image":{"@id":"https:\/\/hedera.com\/#\/schema\/logo\/image\/"}}]}},"featured_image_src":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner-600x400.png","featured_image_src_square":"https:\/\/hedera.com\/wp-content\/uploads\/2025\/12\/Hedera-Token-Service-Banner-600x600.png","author_info":{"display_name":"Hedera Team","author_link":"https:\/\/hedera.com\/blog\/author\/hedera-team\/"},"authors":[{"term_id":43,"user_id":10,"is_guest":0,"slug":"hedera-team","display_name":"Hedera Team","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/7ed01931dc9498365746508c4ca49ed0507ef65e04e0b82ffe88c50ef9242b1d?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":""}],"_links":{"self":[{"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/posts\/15771","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/comments?post=15771"}],"version-history":[{"count":0,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/posts\/15771\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/media\/16882"}],"wp:attachment":[{"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/media?parent=15771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/categories?post=15771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/tags?post=15771"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/hedera.com\/wp-json\/wp\/v2\/ppma_author?post=15771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}