Skip to content

Instantly share code, notes, and snippets.

@abigpotostew
Created March 11, 2022 22:37
Show Gist options
  • Save abigpotostew/1d42c92fd2d22f2fce1a226eba9ff54a to your computer and use it in GitHub Desktop.
Save abigpotostew/1d42c92fd2d22f2fce1a226eba9ff54a to your computer and use it in GitHub Desktop.
// LICENCE MIT
const path = require('path');
const fs = require('fs');
const util = require("util");
// Usage: node analyze-metadata.js <metadata directory> [<output file>]
//
// Calculates the percent of all NFTs that share a given trait in decimal form.
// Also ranks each nft by summing inverse of trait frequency.
// Output format is json:
// {
// "trait-name1": { "trait-value": 0.01 },
// "trait-name2": { "trait-value": 0.01 },
// "all": [ token_1_score,token_2_score, token_3_score, ... ]
// }
// the all array is indexed and sorted by integer of token id, and the highest score is the most rare.
(async ()=>{
const args = process.argv.slice(2)
if (args.length === 0) {
console.log("Usage: node analyze-metadata.js <metadata directory> [<output file>]")
process.exit(1)
}
const traitsMap = new Map()
const read = util.promisify(fs.readdir);
const files = await read(args[0]);
let numNfts = 0;
for (let file of files) {
if (!file.endsWith('.json')) continue;
const data = fs.readFileSync(path.join(args[0], file))
const json = JSON.parse(data.toString())
const traits = json.traits;
numNfts++;
for (let trait of traits) {
const {value,trait_type} = trait;
let curr = traitsMap.get(trait_type)
if(!curr){
curr = {};
}
curr[value] = (curr[value]||0)+1;
traitsMap.set(trait_type, curr)
}
}
const traitsAnalysis = {}
traitsAnalysis.all=[];
for (let [key,value] of traitsMap.entries()){
traitsAnalysis[key] = {};
// console.log(key)
const traitArray = []
Object.keys(value).forEach(v => {
traitArray.push([v, (value[v])])
})
traitArray.sort((a,b)=>{
return b[1] - a[1]
})
for (let t of traitArray) {
traitsAnalysis[key][t[0]] = t[1] / numNfts
// console.log(`\t${(t[1] / numNfts * 100).toFixed(2)}% ${t[0]}`)
}
// console.log('-------------------------------------')
}
const allOrdered = []
for (let file of files) {
if (!file.endsWith('.json')) continue;
const data = fs.readFileSync(path.join(args[0], file))
const json = JSON.parse(data.toString())
const traits = json.traits;
const id =parseInt(file.replace('.json','')).toString();
let score = 0;
for (let trait of traits) {
const {value,trait_type} = trait;
score += 1/traitsAnalysis[trait_type][value]
}
allOrdered.push([id,score])
console.log(id, score)
}
allOrdered.sort((a,b)=>{
return b[1] - a[1]
})
// invert it so that the highest score is first
allOrdered.reverse()
for (let i = 0; i < allOrdered.length; i++) {
traitsAnalysis.all[parseInt(allOrdered[i][0])] = i+1;
}
if(args.length > 1){
fs.writeFileSync(args[1], JSON.stringify(traitsAnalysis, null, 2))
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment