@poprank/rankings
Advanced tools
Comparing version 1.1.5 to 1.1.6
@@ -155,5 +155,29 @@ "use strict"; | ||
var getAllNftsRarity = function (nfts) { | ||
var collection = nfts[0].collection; | ||
// Add all the base traits to the traits we'll add to the NFT, and calculate all "matches" | ||
nfts.forEach(function (nft) { | ||
var _a; | ||
if (rarity_meta_1.ensCollectionSlugs.includes(collection)) { | ||
var max = rarity_meta_1.ensCollectionSizes[collection]; | ||
var digits = max.toString().length - 1; | ||
// Reverse engineer the number value of the ENS given its name or tokenID | ||
var i = 0; | ||
if (nft.name.includes('eth')) { | ||
i = +nft.name.replace('.eth', ''); | ||
} | ||
else { | ||
for (i = 0; i < 10000; i++) { | ||
var id = (0, rarity_meta_1.stringToKeccak256DecimalId)(i.toString(), digits); | ||
// Find the initial integer ID | ||
if (id === nft.id) | ||
break; | ||
} | ||
} | ||
nft.traits.push({ | ||
value: i.toString(), | ||
category: 'Traits', | ||
typeValue: rarity_meta_1.ID_TRAIT_TYPE, | ||
displayType: 'number', | ||
}); | ||
} | ||
(_a = nft.traits).push.apply(_a, (0, exports.getMetaTraits)(nft.traits, nft.collection, true)); | ||
@@ -221,2 +245,6 @@ }); | ||
}); | ||
// Collections for which rarity doesn't make sense | ||
if (rarity_meta_1.ensCollectionSlugs.includes(collection)) { | ||
rarityTraitSum = 0; | ||
} | ||
nftsWithRarity.push(__assign(__assign({}, nft), { traits: nftTraitsWithRarity, rarityTraitSum: +rarityTraitSum.toFixed(3) })); | ||
@@ -223,0 +251,0 @@ }); |
import { TraitBase } from '../types'; | ||
export declare const TRAIT_COUNT = "Trait Count"; | ||
export declare const ID_TRAIT_TYPE = "ID"; | ||
export declare const NONE_TRAIT = "None"; | ||
export declare const ensCollectionSlugs: readonly ["ens", "999club"]; | ||
export declare type EnsCollectionSlug = typeof ensCollectionSlugs[number]; | ||
export declare const ensCollectionSizes: Record<EnsCollectionSlug, number>; | ||
export declare const DAYS_IN_MONTH: { | ||
[k: number]: number; | ||
}; | ||
export declare const stringToKeccak256DecimalId: (s: string, digits: number) => string; | ||
/** | ||
@@ -5,0 +13,0 @@ * All the manual functions we use to add special "meta" traits to collections. |
@@ -13,6 +13,200 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getNftTraitsMatches = exports.collectionNameMetaFunctionPairs = exports.NONE_TRAIT = exports.TRAIT_COUNT = void 0; | ||
exports.getNftTraitsMatches = exports.collectionNameMetaFunctionPairs = exports.stringToKeccak256DecimalId = exports.DAYS_IN_MONTH = exports.ensCollectionSizes = exports.ensCollectionSlugs = exports.NONE_TRAIT = exports.ID_TRAIT_TYPE = exports.TRAIT_COUNT = void 0; | ||
var keccak256_1 = __importDefault(require("keccak256")); | ||
exports.TRAIT_COUNT = 'Trait Count'; | ||
exports.ID_TRAIT_TYPE = 'ID'; | ||
exports.NONE_TRAIT = 'None'; | ||
exports.ensCollectionSlugs = ['ens', '999club']; | ||
exports.ensCollectionSizes = { | ||
'ens': 10000, | ||
'999club': 1000, | ||
}; | ||
exports.DAYS_IN_MONTH = { | ||
1: 31, | ||
2: 29, | ||
3: 31, | ||
4: 30, | ||
5: 31, | ||
6: 30, | ||
7: 31, | ||
8: 31, | ||
9: 30, | ||
10: 31, | ||
11: 30, | ||
12: 31, | ||
}; | ||
function hexToDec(s) { | ||
var i, j, carry; | ||
var digits = [0]; | ||
for (i = 0; i < s.length; i += 1) { | ||
carry = parseInt(s.charAt(i), 16); | ||
for (j = 0; j < digits.length; j += 1) { | ||
digits[j] = digits[j] * 16 + carry; | ||
carry = digits[j] / 10 | 0; | ||
digits[j] %= 10; | ||
} | ||
while (carry > 0) { | ||
digits.push(carry % 10); | ||
carry = carry / 10 | 0; | ||
} | ||
} | ||
return digits.reverse().join(''); | ||
} | ||
var stringToKeccak256DecimalId = function (s, digits) { | ||
return hexToDec((0, keccak256_1.default)("0000".concat(s).slice(-digits)).toString('hex')); | ||
}; | ||
exports.stringToKeccak256DecimalId = stringToKeccak256DecimalId; | ||
var ensMetaFunc = function (nftTraits, outTraits, collection) { | ||
var max = exports.ensCollectionSizes[collection]; | ||
var digits = max.toString().length - 1; | ||
var trait = nftTraits.find(function (t) { return t.displayType === 'number' && t.typeValue === exports.ID_TRAIT_TYPE; }); | ||
if (!trait) | ||
throw new Error("This trait needs a trait with a displayType of 'number' and a typeValue of ".concat(exports.ID_TRAIT_TYPE)); | ||
var i = +trait.value; | ||
var stringified = "000".concat(i).slice(-digits); | ||
// Palindrome trait | ||
var isPalindrome = true; | ||
if (digits === 4) { | ||
var a = 0; | ||
var b = stringified.length - 1; | ||
while (a < b) { | ||
if (stringified[a] !== stringified[b]) { | ||
isPalindrome = false; | ||
break; | ||
} | ||
a++; | ||
b--; | ||
} | ||
} | ||
else if (digits === 3) { | ||
isPalindrome = stringified[0] === stringified[2]; | ||
} | ||
if (isPalindrome) { | ||
outTraits.push({ | ||
value: 'Palindrome', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Prime trait | ||
var isPrime = (['0', '2', '4', '5', '6', '8'].includes(stringified[digits - 1]) && i !== 2 && i !== 5) ? false : true; | ||
var c = 2; | ||
while (c < Math.ceil(Math.sqrt(i)) && isPrime) { | ||
if (i % c === 0) { | ||
isPrime = false; | ||
} | ||
c++; | ||
} | ||
if (isPrime) { | ||
outTraits.push({ | ||
value: 'Prime', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Fibonacci trait | ||
var isFibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765].includes(i); | ||
if (isFibonacci) { | ||
outTraits.push({ | ||
value: 'Fibonacci', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// ABAB trait | ||
var isABAB = stringified.slice(0, 2) === stringified.slice(2); | ||
if (isABAB) { | ||
outTraits.push({ | ||
value: 'ABAB Repeat', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Double (0331, 0013, 3122, etc) trait | ||
var isDouble = false; | ||
stringified.split('').forEach(function (char, index) { | ||
if (!index) | ||
return; | ||
if (stringified[index - 1] === char) | ||
isDouble = true; | ||
}); | ||
if (isDouble) { | ||
outTraits.push({ | ||
value: 'Double', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Double (0331, 0013, 3122, etc) trait | ||
var isDoublePair = stringified[0] === stringified[1] && stringified[2] === stringified[3]; | ||
if (isDoublePair) { | ||
outTraits.push({ | ||
value: 'Double Pair', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Birthday trait | ||
var day = +stringified.slice(0, 2); | ||
var month = +stringified.slice(2, 4); | ||
var isBirthday = month >= 1 && month <= 12 && day >= 1 && day <= exports.DAYS_IN_MONTH[month]; | ||
if (isBirthday) { | ||
outTraits.push({ | ||
value: 'Birthday', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Birthday (US) trait | ||
var usMonth = +stringified.slice(0, 2); | ||
var usDay = +stringified.slice(2, 4); | ||
var isUSBirthday = usMonth >= 1 && usMonth <= 12 && usDay >= 1 && usDay <= exports.DAYS_IN_MONTH[usMonth]; | ||
if (isUSBirthday) { | ||
outTraits.push({ | ||
value: 'Birthday (US)', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Triple Digits | ||
var isTriple = false; | ||
for (var j = 0; j < stringified.length - 3; j++) { | ||
if (['000', '111', '222', '333', '444', '555', '666', '777', '888', '999'].includes(stringified.slice(j, j + 3))) | ||
isTriple = true; | ||
} | ||
if (isTriple) { | ||
outTraits.push({ | ||
value: 'Triple', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
// Triple Digits | ||
var isQuadruple = false; | ||
for (var j = 0; j < stringified.length - 4; j++) { | ||
if (['0000', '1111', '2222', '3333', '4444', '5555', '6666', '7777', '8888', '9999'].includes(stringified.slice(j, j + 4))) | ||
isQuadruple = true; | ||
} | ||
if (isQuadruple) { | ||
outTraits.push({ | ||
value: 'Quadruple', | ||
category: 'Meta', | ||
typeValue: 'Special', | ||
displayType: null, | ||
}); | ||
} | ||
}; | ||
/** | ||
@@ -74,3 +268,8 @@ * All the manual functions we use to add special "meta" traits to collections. | ||
}, | ||
}]; | ||
}, { | ||
'ens': function (nftTraits, outTraits) { return ensMetaFunc(nftTraits, outTraits, 'ens'); }, | ||
}, { | ||
'999club': function (nftTraits, outTraits) { return ensMetaFunc(nftTraits, outTraits, '999club'); }, | ||
}, | ||
]; | ||
/** | ||
@@ -86,3 +285,3 @@ * Get the "match" traits for a collection. Has some collection-specific logic to add desired | ||
nftTraits.forEach(function (n) { | ||
var scrubbedValue = n.value; | ||
var scrubbedValue = "".concat(n.value); | ||
// Ignore all "None" traits | ||
@@ -93,10 +292,10 @@ if (scrubbedValue === exports.NONE_TRAIT) | ||
if (collection === 'mutant-ape-yacht-club') | ||
scrubbedValue = n.value.split(' ').slice(1).join(' '); | ||
scrubbedValue = scrubbedValue.split(' ').slice(1).join(' '); | ||
// Attempt to match "Skin - Blue" and "Shirt - Light Blue" | ||
if (collection === 'doodles-official') { | ||
scrubbedValue = n.value.toLowerCase().replace('light ', ''); | ||
scrubbedValue = scrubbedValue.toLowerCase().replace('light ', ''); | ||
} | ||
// Grab the first word of the trait type. This is to try match "Blue Shirt" and "Blue Hat". | ||
// Will likely make this more intelligent in the future, this is just a simple implementation | ||
scrubbedValue = n.value.split(' ')[0].toLowerCase(); | ||
scrubbedValue = scrubbedValue.split(' ')[0].toLowerCase(); | ||
if (!traitValueMatches[scrubbedValue]) { | ||
@@ -103,0 +302,0 @@ traitValueMatches[scrubbedValue] = 0; |
{ | ||
"name": "@poprank/rankings", | ||
"version": "1.1.5", | ||
"version": "1.1.6", | ||
"description": "PopRank's NFT rarity and aesthetic ranking logic", | ||
@@ -19,3 +19,6 @@ "publishConfig": { | ||
"types": "lib/index.d.ts", | ||
"dependencies": {}, | ||
"dependencies": { | ||
"@types/bn.js": "^5.1.0", | ||
"keccak256": "^1.0.6" | ||
}, | ||
"devDependencies": { | ||
@@ -47,2 +50,2 @@ "@types/jest": "^27.4.1", | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
55712
765
2
+ Added@types/bn.js@^5.1.0
+ Addedkeccak256@^1.0.6
+ Added@types/bn.js@5.1.6(transitive)
+ Added@types/node@22.9.0(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbn.js@5.2.1(transitive)
+ Addedbuffer@6.0.3(transitive)
+ Addedieee754@1.2.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedkeccak@3.0.4(transitive)
+ Addedkeccak256@1.0.6(transitive)
+ Addednode-addon-api@2.0.2(transitive)
+ Addednode-gyp-build@4.8.2(transitive)
+ Addedreadable-stream@3.6.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedstring_decoder@1.3.0(transitive)
+ Addedundici-types@6.19.8(transitive)
+ Addedutil-deprecate@1.0.2(transitive)