Created
March 11, 2022 22:37
-
-
Save abigpotostew/1d42c92fd2d22f2fce1a226eba9ff54a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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