Skip to content

Commit d44d272

Browse files
committed
add rarity calculator
1 parent d680bec commit d44d272

File tree

6 files changed

+140
-8
lines changed

6 files changed

+140
-8
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ build/
5353
dist/
5454
node_modules/
5555
jspm_packages/
56+
package-lock.json
57+
yarn.lock
5658

5759
# TypeScript v1 declaration files
5860

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Join the Discord server for more help from the community: [codeSTACKr Discord](h
1414

1515
The macro script from the second video: [macro1.mmmacro](macro1.mmmacro)
1616

17+
UPDATE: Added rarity calculator. See this [video](https://youtu.be/Uz1y4j9gvP8) for the walkthrough.
18+
1719
## UPDATES & FIXES
1820

1921
### npm not recognized
@@ -45,9 +47,11 @@ Ensure that your layer names in the `config.js` file match exactly to your layer
4547

4648
### "Quota Limit Reached" or "Too many requests" errors
4749

48-
There have been some changes made to the code from the original video resulting from some errors when uploading files, metadata, and minting using NFTPort. Depending on your plan, Free vs Community, there are rate limits.
50+
There have been some changes made to the code from the original video resulting from some errors when uploading files, metadata, and minting using NFTPort. Depending on your plan, Free vs Community, there are rate limits.
51+
52+
To fix these issues, I've updated the code to include a timeout that will allow the files to be uploaded at a slower rate, instead of all at once, eliminating these errors.
4953

50-
To fix these issues, I've updated the code to include a timeout that will allow the files to be uploaded at a slower rate, instead of all at once, eliminating these errors.
54+
If you've reached your quota limit, contact NFTPort to upgrade your plan to get more.
5155

5256
**To use this code:**
5357

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "10k-collection-video",
3-
"version": "1.1.0",
3+
"version": "1.2.0",
44
"description": "Source code from \"How To Create An ENTIRE NFT Collection (10,000+) & MINT In Under 1 Hour Without Coding Knowledge\" video.",
55
"main": "index.js",
66
"bin": "index.js",
@@ -15,6 +15,8 @@
1515
"build": "node index.js",
1616
"generate": "node index.js",
1717
"rarity": "node utils/rarity.js",
18+
"rarity_md": "node utils/getRarity_fromMetadata.js",
19+
"rarity_rank": "node utils/rarity_rank.js",
1820
"preview": "node utils/preview.js",
1921
"pixelate": "node utils/pixelate.js",
2022
"update_info": "node utils/update_info.js",

utils/getRarity_fromMetadata.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const basePath = process.cwd();
2+
const fs = require("fs");
3+
4+
const getRarity = () => {
5+
// read json data
6+
const rawdata = fs.readFileSync(`${basePath}/build/json/_metadata.json`);
7+
const nfts = JSON.parse(rawdata);
8+
9+
processRarity(nfts)
10+
}
11+
12+
function processRarity(nfts) {
13+
const rarity = {}
14+
15+
// loop through all nfts
16+
for(const nft of nfts) {
17+
// check if attributes exist
18+
if(nft?.attributes?.length > 0) {
19+
// loop through all attributes
20+
for(attribute of nft.attributes) {
21+
// add trait type to rarity object if it doesn't exist
22+
if(!rarity[attribute.trait_type]) {
23+
rarity[attribute.trait_type] = {}
24+
}
25+
// add attribute value to rarity object if it doesn't exist and set count to 0
26+
if(!rarity[attribute.trait_type][attribute.value]) {
27+
rarity[attribute.trait_type][attribute.value] = {
28+
count: 0
29+
}
30+
}
31+
// increment count of trait type
32+
rarity[attribute.trait_type][attribute.value].count++
33+
// add rarity score to rarity object for each trait type
34+
rarity[attribute.trait_type][attribute.value].rarityScore = (1 / (rarity[attribute.trait_type][attribute.value].count / nfts.length)).toFixed(2)
35+
}
36+
}
37+
}
38+
39+
// create a total rarity score for each nft by adding up all the rarity scores for each trait type
40+
nfts.map(nft => {
41+
if(nft?.attributes?.length > 0) {
42+
let totalScore = 0;
43+
for(attribute of nft.attributes) {
44+
attribute.rarity_score = rarity[attribute.trait_type][attribute.value].rarityScore
45+
totalScore += parseFloat(attribute.rarity_score)
46+
}
47+
nft.total_rarity_score = +parseFloat(totalScore).toFixed(2)
48+
}
49+
})
50+
51+
// sort nfts by total rarity score
52+
nfts.sort((a, b) => b.total_rarity_score - a.total_rarity_score)
53+
54+
// add rank to nfts
55+
nfts.map((nft, index) => {
56+
nft.rank = index + 1
57+
})
58+
59+
// sort nfts by edition again
60+
nfts.sort((a, b) => a.custom_fields.edition - b.custom_fields.edition)
61+
62+
fs.writeFileSync(`${basePath}/build/json/_metadata_with_rarity.json`, JSON.stringify(nfts, null, 2));
63+
}
64+
65+
getRarity();

utils/rarity_rank.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const basePath = process.cwd();
2+
const fs = require("fs");
3+
4+
// initialize readline to prompt user for input
5+
const readline = require("readline");
6+
const rl = readline.createInterface({
7+
input: process.stdin,
8+
output: process.stdout,
9+
});
10+
const prompt = (query) => new Promise((resolve) => rl.question(query, resolve));
11+
12+
(async () => {
13+
try {
14+
// read json data
15+
const rawdata = fs.readFileSync(
16+
`${basePath}/build/json/_metadata_with_rarity.json`
17+
);
18+
const nfts = JSON.parse(rawdata);
19+
20+
// prompt user to choose how to list nfts
21+
// 1. get top ## nfts
22+
// 2. get a specific nft by edition
23+
const choice = await prompt(
24+
"Enter 1 to get top ## NFTs by rarity or 2 to get a specific NFTs rarity: "
25+
);
26+
27+
if (choice === "1") {
28+
const top = await prompt("Enter the number of NFTs you want to get: ");
29+
const sortedNfts = nfts.sort(
30+
(a, b) => b.total_rarity_score - a.total_rarity_score
31+
);
32+
const topNfts = sortedNfts.slice(0, top);
33+
console.log(
34+
topNfts.map(({ rank, total_rarity_score, name }) => {
35+
return {
36+
name,
37+
rank,
38+
total_rarity_score,
39+
};
40+
})
41+
);
42+
} else if (choice === "2") {
43+
const nftEdition = await prompt("Enter the NFT Edition: ");
44+
const nft = nfts.find((nft) => nft.custom_fields.edition === +nftEdition);
45+
console.log({
46+
name: nft.name,
47+
rank: nft.rank,
48+
total_rarity_score: nft.total_rarity_score,
49+
});
50+
} else {
51+
console.log("Invalid choice. Enter either 1 or 2.");
52+
}
53+
54+
// close readline
55+
rl.close();
56+
} catch (e) {
57+
console.error("unable to prompt", e);
58+
}
59+
})();

0 commit comments

Comments
 (0)