Hedera NFT Utilities
This package includes all sorts of tooling for the Hedera NFT ecosystem, including:
- HIP412 metadata validation: Verify your metadata against the HIP412 metadata standard for NFTs, which returns errors and warnings against the standard.
- Local metadata validator: Verify a local folder containing multiple JSON metadata files against the standard before publishing the NFT collection on the Hedera network.
- Risk score calculation: Calculate a risk score for an NFT collection from the token information or by passing a token ID of an NFT on the Hedera testnet or mainnet.
- Rarity score calculation: Calculate the rarity scores for a local folder containing multiple JSON metadata files for an NFT collection.
Table of Contents
HIP412 metadata validator
Verify your metadata against the HIP412 metadata standard for NFTs which returns errors and warnings against the standard.
Usage
Install the package:
npm i -s @hashgraph/nft-utilities
Import the package into your project. You can import the validator
function and the default schema version for HIP412 with defaultVersion
.
const { validator, defaultVersion } = require('@hashgraph/nft-utilities');
You can use the validator
like below.
- The first parameter is the stringified JSON object you want to verify against a JSON schema
- The second parameter is the version of HIP412 metadata schema against which you want to validate your metadata instance. The default value is
2.0.0
. In the future, new functionality might be added, releasing new version numbers.
const metadata = {
attributes: [
{ trait_type: "Background", value: "Yellow" }
],
creator: "NFT artist",
};
const version = '2.0.0';
const issues = validator(JSON.stringify(metadata), version);
Interface
The output interface for issues contains errors
and warnings
.
{
"errors": [
{
"type": "Indicates which validator created the error. Possible values: schema, attribute, localization, and SHA256.",
"msg": "Indicates the specific error explanation to be displayed to the user",
"path": "Indicates the path of the property for which the error is returned"
}
],
"warnings": [
{
"type": "schema",
"msg": "is not allowed to have the additional property 'someAdditionalProperty'",
"path": "Indicates the path of the property for which the error is returned"
}
]
}
Here's an example:
{
"errors": [
{
"type": "attribute",
"msg": "Trait stamina of type 'percentage' must be between [0-100], found 157",
"path": "instance.attributes[0]"
}
],
"warnings": [
{
"type": "schema",
"msg": "is not allowed to have the additional property 'imagePreview'",
"path": "instance"
}
]
}
Examples
See: /examples/HIP412-metadata-validator
Add custom schema versions
You can add custom JSON schemas to the /schemas
folder.
You can then add the version to the schemaMap
in /schema/index.js
using the following code:
const HIP412_2_0_0 = require("./HIP412@2.0.0.json");
const myCustomSchema = require("./myschema.json");
const schemaMap = new Map();
schemaMap.set('2.0.0', HIP412_2_0_0);
schemaMap.set('<version>', myCustomSchema);
When you've added your schema to the map, you can validate against your schema version by passing your version to the validator()
function.
Add custom validation rules
Set custom validation rules by importing new validators from the /validators
folder into the index.js
file. You can then add them to the validator()
function. Stick to the issues
format of errors and warnings (see section "Issues format" for the detailed description).
const { myCustomValidator, schemaValidator } = require("./validators");
const validator = (instance, schemaVersion = defaultVersion) => {
let errors = [];
let warnings = [];
const schema = getSchema(schemaVersion)
const schemaProblems = schemaValidator(instance, schema);
warnings.push(...schemaProblems.warnings);
if (schemaProblems.errors.length > 0) {
errors.push(...schemaProblems.errors);
return {
errors,
warnings
}
}
const customErrors = myCustomValidator(instance);
errors.push(...customErrors);
return {
errors,
warnings
};
}
Local validator
Verify a local folder containing multiple JSON metadata files against the standard before publishing the NFT collection on the Hedera network.
Usage
Install the package:
npm i -s @hashgraph/nft-utilities
Import the package into your project and get the localValidation
function.
const { localValidation } = require('@hashgraph/nft-utilities');
The localValidation
expects an absolute path to your metadata files to verify them. The function prints the warnings and errors for all JSON files it finds in the provided folder path. It also returns the validation results as an object in case you want to use the results in your code.
localValidation("/Users/projects/nft/files");
This package uses the validator
function explained in the previous section.
Interface
The output interface for this function looks like this.
{
"filename.json": {
"errors": [
{
"type": "Indicates which validator created the error. Possible values: schema, attribute, localization, and SHA256.",
"msg": "Indicates the specific error explanation to be displayed to the user",
"path": "Indicates the path of the property for which the error is returned"
}
],
"warnings": [
{
"type": "schema",
"msg": "is not allowed to have the additional property 'someAdditionalProperty'",
"path": "Indicates the path of the property for which the error is returned"
}
]
},
"filename2.json": ...
}
Examples
See: /examples/local-metadata-validator/index.js
Risk score calculation
Calculate risk score for a token from the token information or by passing a token ID of an NFT on the Hedera testnet or mainnet.
The total risk score is calculated based on the presence of certain keys
for the token or the presence of an INFINITE
supply_type
. Each key or property has an associated weight.
const defaultWeights = {
keys: {
admin_key: 200,
wipe_key: 200,
freeze_key: 50,
supply_key: 20,
kyc_key: 50,
pause_key: 50,
fee_schedule_key: 40
},
properties: {
supply_type_infinite: 20
}
};
To determine the risk level, there are four categories each with an attached score. If the score is lower than or equal to a risk level, it will get that risk level. E.g. a token with a risk score of 200 will get a HIGH
risk level.
const defaultRiskLevels = {
NORISK: 0,
LOW: 40,
MEDIUM: 199,
HIGH: 2000
};
Usage
Install the package:
npm i -s @hashgraph/nft-utilities
Import the package into your project and get the calculateRiskScoreFromData
or calculateRiskScoreFromTokenId
functions.
const { calculateRiskScoreFromData, calculateRiskScoreFromTokenId } = require('@hashgraph/nft-utilities');
The calculateRiskScoreFromData
expects a token information JSON object as returned by the /api/v1/tokens/ endpoint (here's an example of token data).
const tokenInformation = {
"admin_key": null,
"auto_renew_account": "0.0.784037", "auto_renew_period": 7776000,
"freeze_key": null,
...
}
const results = calculateRiskScoreFromData(tokenInformation);
Alternatively, use the calculateRiskScoreFromTokenId
to retrieve risk information about a token by entering a token ID. This asynchronous function looks up the token information from the mirror node and returns the risk information.
const results = await calculateRiskScoreFromTokenId("0.0.1270555");
Interface
The output interface for this function looks like this.
{
"riskScore": "number representing total risk score",
"riskLevel": "<string: ENUM(NORISK, LOW, MEDIUM, HIGH)>"
}
Examples
See: /examples/risk-score-calculation
Rarity score calculation
Calculate the rarity for a local folder containing multiple JSON metadata files for an NFT collection. This package uses the trait normalization rarity scoring model because it's the fairest model to calculate rarity.
The model works by dividing the number one by the division of the number of NFTs with a specific trait value and the number of NFTs with the most common trait value for that trait. Here's the formula:
1 / (# of NFTs with trait value / # of NFTs with most common trait value)
This model outputs a score for each NFT. By sorting the NFTs, you'll get a ranking based on this scoring model.
Usage
Install the package:
npm i -s @hashgraph/nft-utilities
Import the package into your project and get calculateRarity
function. Next, you need to pass an absolute path to a folder containing metadata JSON files.
const { calculateRarity } = require('@hashgraph/nft-utilities');
const absolutePathToFiles = "/Users/myUser/nft-utilities/examples/rarity-score-calculation/files";
const results = calculateRarity(absolutePathToFiles);
console.log(results)
According to HIP412, the calculateRarity
function only looks at objects in the attributes
property that use the following format:
{ "trait_type": "Background", "value": "Yellow" }
OR
{ "trait_type": "Background", "value": 10, "display_type": "percentage" }
Interface
The output interface for this function looks like this.
[
{ "rarity": "<string> rarity score", "NFT": "<nubmer> NFT number", "filename": "<string>" },
...
]
Here's a sample output:
[
{ rarity: '5.50', NFT: 1, filename: 'nft1.json' },
{ rarity: '6.00', NFT: 2, filename: 'nft2.json' },
{ rarity: '5.50', NFT: 3, filename: 'nft3.json' },
{ rarity: '5.50', NFT: 4, filename: 'nft4.json' },
{ rarity: '11.50', NFT: 5, filename: 'nft5.json' }
]
Examples
See: /examples/rarity-score-calculation/index.js
Questions or Improvement Proposals
Please create an issue or PR on this repository. Make sure to join the Hedera Discord server to ask questions or discuss improvement suggestions.
Support
If you have a question on how to use the product, please see our
support guide.
Contributing
Contributions are welcome. Please see the
contributing guide
to see how you can get involved.
Code of Conduct
This project is governed by the
Contributor Covenant Code of Conduct. By
participating, you are expected to uphold this code of conduct. Please report unacceptable behavior
to oss@hedera.com.
License
Apache License 2.0