@xyo-network/crypto-nft-diviner-score-plugin 2.95.5 → 2.96.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.cjs +38 -76
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +38 -76
- package/dist/browser/index.js.map +1 -1
- package/dist/neutral/index.cjs +38 -76
- package/dist/neutral/index.cjs.map +1 -1
- package/dist/neutral/index.js +38 -76
- package/dist/neutral/index.js.map +1 -1
- package/dist/node/index.cjs +38 -76
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +38 -76
- package/dist/node/index.js.map +1 -1
- package/package.json +13 -12
package/dist/browser/index.cjs
CHANGED
|
@@ -38,12 +38,9 @@ var import_payload_builder = require("@xyo-network/payload-builder");
|
|
|
38
38
|
var import_crypto_nft_score_model = require("@xyo-network/crypto-nft-score-model");
|
|
39
39
|
var import_ethers = require("ethers");
|
|
40
40
|
var scoreContractAddress = (nft) => {
|
|
41
|
-
if (!nft.address)
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
return import_crypto_nft_score_model.FAIL;
|
|
45
|
-
if (!(0, import_ethers.isAddress)(nft.address))
|
|
46
|
-
return import_crypto_nft_score_model.FAIL;
|
|
41
|
+
if (!nft.address) return import_crypto_nft_score_model.FAIL;
|
|
42
|
+
if (typeof nft.address !== "string") return import_crypto_nft_score_model.FAIL;
|
|
43
|
+
if (!(0, import_ethers.isAddress)(nft.address)) return import_crypto_nft_score_model.FAIL;
|
|
47
44
|
return import_crypto_nft_score_model.PASS;
|
|
48
45
|
};
|
|
49
46
|
|
|
@@ -54,8 +51,7 @@ var import_crypto_nft_score_model2 = require("@xyo-network/crypto-nft-score-mode
|
|
|
54
51
|
var import_url = require("@xylabs/url");
|
|
55
52
|
var web3Protocols = ["ipfs:", "ar:"];
|
|
56
53
|
var toUrl = (url) => {
|
|
57
|
-
if (!url)
|
|
58
|
-
return void 0;
|
|
54
|
+
if (!url) return void 0;
|
|
59
55
|
try {
|
|
60
56
|
return new import_url.URL(url);
|
|
61
57
|
} catch {
|
|
@@ -72,20 +68,15 @@ var scoreNftAnimationUrl = (nft) => {
|
|
|
72
68
|
};
|
|
73
69
|
var scoreAnimationUrl = (animation_url) => {
|
|
74
70
|
const score = [0, 0];
|
|
75
|
-
if (animation_url === void 0 || animation_url === null)
|
|
76
|
-
return import_crypto_nft_score_model2.PASS;
|
|
71
|
+
if (animation_url === void 0 || animation_url === null) return import_crypto_nft_score_model2.PASS;
|
|
77
72
|
(0, import_crypto_nft_score_model2.incrementPossible)(score);
|
|
78
|
-
if (typeof animation_url !== "string")
|
|
79
|
-
return score;
|
|
73
|
+
if (typeof animation_url !== "string") return score;
|
|
80
74
|
(0, import_crypto_nft_score_model2.incrementTotalAndPossible)(score);
|
|
81
|
-
if (!isValidUrl(animation_url))
|
|
82
|
-
return score;
|
|
75
|
+
if (!isValidUrl(animation_url)) return score;
|
|
83
76
|
(0, import_crypto_nft_score_model2.incrementTotalAndPossible)(score);
|
|
84
|
-
if (!isSecure(animation_url))
|
|
85
|
-
return score;
|
|
77
|
+
if (!isSecure(animation_url)) return score;
|
|
86
78
|
(0, import_crypto_nft_score_model2.incrementTotalAndPossible)(score);
|
|
87
|
-
if (!isWeb3(animation_url))
|
|
88
|
-
return score;
|
|
79
|
+
if (!isWeb3(animation_url)) return score;
|
|
89
80
|
return (0, import_crypto_nft_score_model2.incrementTotal)(score);
|
|
90
81
|
};
|
|
91
82
|
|
|
@@ -108,8 +99,7 @@ var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
|
108
99
|
var isNonEmptyStringOrNumber = (value) => value === "number" || isNonEmptyString(value);
|
|
109
100
|
var evaluateNftAttributes = (nft) => nft?.metadata?.attributes ? evaluateAttributes(nft?.metadata?.attributes) : [0, 1];
|
|
110
101
|
var evaluateAttributes = (attributes) => {
|
|
111
|
-
if (!attributes || !Array.isArray(attributes) || attributes.length === 0)
|
|
112
|
-
return [0, 1];
|
|
102
|
+
if (!attributes || !Array.isArray(attributes) || attributes.length === 0) return [0, 1];
|
|
113
103
|
const score = [0, 0];
|
|
114
104
|
for (const attribute of attributes) {
|
|
115
105
|
const [attributeTotal, attributePossible] = evaluateAttribute(attribute);
|
|
@@ -122,16 +112,13 @@ var evaluateAttribute = (attribute) => {
|
|
|
122
112
|
const max_value = attribute?.max_value;
|
|
123
113
|
const trait_type = attribute?.trait_type;
|
|
124
114
|
const value = attribute?.value;
|
|
125
|
-
if (!attribute || typeof attribute !== "object" || !isNonEmptyString(trait_type) || !isNonEmptyStringOrNumber(value))
|
|
126
|
-
return score;
|
|
115
|
+
if (!attribute || typeof attribute !== "object" || !isNonEmptyString(trait_type) || !isNonEmptyStringOrNumber(value)) return score;
|
|
127
116
|
(0, import_crypto_nft_score_model3.incrementTotal)(score);
|
|
128
117
|
(0, import_crypto_nft_score_model3.incrementPossible)(score);
|
|
129
|
-
if (validDisplayType(attribute))
|
|
130
|
-
(0, import_crypto_nft_score_model3.incrementTotal)(score);
|
|
118
|
+
if (validDisplayType(attribute)) (0, import_crypto_nft_score_model3.incrementTotal)(score);
|
|
131
119
|
if (max_value !== void 0) {
|
|
132
120
|
(0, import_crypto_nft_score_model3.incrementPossible)(score);
|
|
133
|
-
if (isNumber(max_value) && isNumber(value) && value <= max_value)
|
|
134
|
-
(0, import_crypto_nft_score_model3.incrementTotal)(score);
|
|
121
|
+
if (isNumber(max_value) && isNumber(value) && value <= max_value) (0, import_crypto_nft_score_model3.incrementTotal)(score);
|
|
135
122
|
}
|
|
136
123
|
return score;
|
|
137
124
|
};
|
|
@@ -139,24 +126,20 @@ var validDisplayType = (attribute) => {
|
|
|
139
126
|
switch (attribute?.display_type) {
|
|
140
127
|
case "number":
|
|
141
128
|
case "boost_number": {
|
|
142
|
-
if (isNumber(attribute?.value))
|
|
143
|
-
return true;
|
|
129
|
+
if (isNumber(attribute?.value)) return true;
|
|
144
130
|
break;
|
|
145
131
|
}
|
|
146
132
|
case "boost_percentage": {
|
|
147
|
-
if (isPercentage(attribute?.value))
|
|
148
|
-
return true;
|
|
133
|
+
if (isPercentage(attribute?.value)) return true;
|
|
149
134
|
break;
|
|
150
135
|
}
|
|
151
136
|
case "date": {
|
|
152
|
-
if (isDate(attribute?.value))
|
|
153
|
-
return true;
|
|
137
|
+
if (isDate(attribute?.value)) return true;
|
|
154
138
|
break;
|
|
155
139
|
}
|
|
156
140
|
case "string":
|
|
157
141
|
case void 0: {
|
|
158
|
-
if (isNonEmptyString(attribute?.value))
|
|
159
|
-
return true;
|
|
142
|
+
if (isNonEmptyString(attribute?.value)) return true;
|
|
160
143
|
break;
|
|
161
144
|
}
|
|
162
145
|
default: {
|
|
@@ -174,14 +157,11 @@ var scoreNftBackgroundColor = (nft) => {
|
|
|
174
157
|
};
|
|
175
158
|
var scoreBackgroundColor = (background_color) => {
|
|
176
159
|
const score = [0, 0];
|
|
177
|
-
if (background_color === void 0 || background_color === null)
|
|
178
|
-
return import_crypto_nft_score_model4.PASS;
|
|
160
|
+
if (background_color === void 0 || background_color === null) return import_crypto_nft_score_model4.PASS;
|
|
179
161
|
(0, import_crypto_nft_score_model4.incrementPossible)(score);
|
|
180
|
-
if (typeof background_color !== "string")
|
|
181
|
-
return score;
|
|
162
|
+
if (typeof background_color !== "string") return score;
|
|
182
163
|
(0, import_crypto_nft_score_model4.incrementTotalAndPossible)(score);
|
|
183
|
-
if (!isHexColor.test(background_color.toUpperCase()))
|
|
184
|
-
return score;
|
|
164
|
+
if (!isHexColor.test(background_color.toUpperCase())) return score;
|
|
185
165
|
return (0, import_crypto_nft_score_model4.incrementTotal)(score);
|
|
186
166
|
};
|
|
187
167
|
|
|
@@ -192,8 +172,7 @@ var scoreNftDescription = (nft) => {
|
|
|
192
172
|
};
|
|
193
173
|
var scoreDescription = (description) => {
|
|
194
174
|
const score = [0, 1];
|
|
195
|
-
if (!description || typeof description !== "string")
|
|
196
|
-
return score;
|
|
175
|
+
if (!description || typeof description !== "string") return score;
|
|
197
176
|
return (0, import_crypto_nft_score_model5.incrementTotal)(score);
|
|
198
177
|
};
|
|
199
178
|
|
|
@@ -204,11 +183,9 @@ var scoreNftExternalUrl = (nft) => {
|
|
|
204
183
|
};
|
|
205
184
|
var scoreExternalUrl = (external_url) => {
|
|
206
185
|
const score = [0, 2];
|
|
207
|
-
if (external_url === void 0 || external_url === null || typeof external_url !== "string" || !isValidUrl(external_url))
|
|
208
|
-
return score;
|
|
186
|
+
if (external_url === void 0 || external_url === null || typeof external_url !== "string" || !isValidUrl(external_url)) return score;
|
|
209
187
|
(0, import_crypto_nft_score_model6.incrementTotal)(score);
|
|
210
|
-
if (!isSecure(external_url))
|
|
211
|
-
return score;
|
|
188
|
+
if (!isSecure(external_url)) return score;
|
|
212
189
|
return (0, import_crypto_nft_score_model6.incrementTotal)(score);
|
|
213
190
|
};
|
|
214
191
|
|
|
@@ -224,14 +201,11 @@ var scoreNftImage = (nft) => {
|
|
|
224
201
|
};
|
|
225
202
|
var scoreImage = (image) => {
|
|
226
203
|
const score = [0, MaxPossibleImageScore];
|
|
227
|
-
if (!image || typeof image !== "string" || !isValidUrl(image))
|
|
228
|
-
return score;
|
|
204
|
+
if (!image || typeof image !== "string" || !isValidUrl(image)) return score;
|
|
229
205
|
(0, import_crypto_nft_score_model7.incrementTotal)(score);
|
|
230
|
-
if (!isSecure(image))
|
|
231
|
-
return score;
|
|
206
|
+
if (!isSecure(image)) return score;
|
|
232
207
|
(0, import_crypto_nft_score_model7.incrementTotal)(score);
|
|
233
|
-
if (!isWeb3(image))
|
|
234
|
-
return score;
|
|
208
|
+
if (!isWeb3(image)) return score;
|
|
235
209
|
(0, import_crypto_nft_score_model7.incrementTotal)(score);
|
|
236
210
|
return score;
|
|
237
211
|
};
|
|
@@ -241,8 +215,7 @@ var import_crypto_nft_score_model8 = require("@xyo-network/crypto-nft-score-mode
|
|
|
241
215
|
var import_svg_parser = require("svg-parser");
|
|
242
216
|
var MaxPossibleImageDataScore = 1;
|
|
243
217
|
var isValidImageData = (image_data) => {
|
|
244
|
-
if (!image_data.startsWith("<svg"))
|
|
245
|
-
return false;
|
|
218
|
+
if (!image_data.startsWith("<svg")) return false;
|
|
246
219
|
try {
|
|
247
220
|
(0, import_svg_parser.parse)(image_data);
|
|
248
221
|
return true;
|
|
@@ -268,8 +241,7 @@ var scoreNftName = (nft) => {
|
|
|
268
241
|
};
|
|
269
242
|
var scoreName = (name) => {
|
|
270
243
|
const score = [0, 1];
|
|
271
|
-
if (!name || typeof name !== "string")
|
|
272
|
-
return score;
|
|
244
|
+
if (!name || typeof name !== "string") return score;
|
|
273
245
|
return (0, import_crypto_nft_score_model9.incrementTotal)(score);
|
|
274
246
|
};
|
|
275
247
|
|
|
@@ -279,24 +251,19 @@ var scoreNftYoutubeUrl = (nft) => {
|
|
|
279
251
|
return scoreYoutubeUrl(nft?.metadata?.youtube_url);
|
|
280
252
|
};
|
|
281
253
|
var scoreYoutubeUrl = (youtube_url) => {
|
|
282
|
-
if (youtube_url === void 0 || youtube_url === null)
|
|
283
|
-
return import_crypto_nft_score_model10.PASS;
|
|
254
|
+
if (youtube_url === void 0 || youtube_url === null) return import_crypto_nft_score_model10.PASS;
|
|
284
255
|
const score = [0, 2];
|
|
285
|
-
if (typeof youtube_url !== "string" || !isValidUrl(youtube_url))
|
|
286
|
-
return score;
|
|
256
|
+
if (typeof youtube_url !== "string" || !isValidUrl(youtube_url)) return score;
|
|
287
257
|
(0, import_crypto_nft_score_model10.incrementTotal)(score);
|
|
288
|
-
if (!isSecure(youtube_url))
|
|
289
|
-
return score;
|
|
258
|
+
if (!isSecure(youtube_url)) return score;
|
|
290
259
|
return (0, import_crypto_nft_score_model10.incrementTotal)(score);
|
|
291
260
|
};
|
|
292
261
|
|
|
293
262
|
// src/lib/rating/criteria/scoring/supply.ts
|
|
294
263
|
var import_crypto_nft_score_model11 = require("@xyo-network/crypto-nft-score-model");
|
|
295
264
|
var scoreSupply = (nft) => {
|
|
296
|
-
if (!nft.supply)
|
|
297
|
-
|
|
298
|
-
if (typeof nft.supply !== "string")
|
|
299
|
-
return import_crypto_nft_score_model11.FAIL;
|
|
265
|
+
if (!nft.supply) return import_crypto_nft_score_model11.FAIL;
|
|
266
|
+
if (typeof nft.supply !== "string") return import_crypto_nft_score_model11.FAIL;
|
|
300
267
|
try {
|
|
301
268
|
return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? import_crypto_nft_score_model11.PASS : import_crypto_nft_score_model11.FAIL;
|
|
302
269
|
} catch {
|
|
@@ -307,10 +274,8 @@ var scoreSupply = (nft) => {
|
|
|
307
274
|
// src/lib/rating/criteria/scoring/tokenId.ts
|
|
308
275
|
var import_crypto_nft_score_model12 = require("@xyo-network/crypto-nft-score-model");
|
|
309
276
|
var scoreTokenId = (nft) => {
|
|
310
|
-
if (!nft.tokenId)
|
|
311
|
-
|
|
312
|
-
if (typeof nft.tokenId !== "string")
|
|
313
|
-
return import_crypto_nft_score_model12.FAIL;
|
|
277
|
+
if (!nft.tokenId) return import_crypto_nft_score_model12.FAIL;
|
|
278
|
+
if (typeof nft.tokenId !== "string") return import_crypto_nft_score_model12.FAIL;
|
|
314
279
|
try {
|
|
315
280
|
return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? import_crypto_nft_score_model12.PASS : import_crypto_nft_score_model12.FAIL;
|
|
316
281
|
} catch {
|
|
@@ -321,13 +286,10 @@ var scoreTokenId = (nft) => {
|
|
|
321
286
|
// src/lib/rating/criteria/scoring/type.ts
|
|
322
287
|
var import_crypto_nft_score_model13 = require("@xyo-network/crypto-nft-score-model");
|
|
323
288
|
var scoreType = (nft) => {
|
|
324
|
-
if (!nft.type)
|
|
325
|
-
|
|
326
|
-
if (typeof nft.type !== "string")
|
|
327
|
-
return import_crypto_nft_score_model13.FAIL;
|
|
289
|
+
if (!nft.type) return import_crypto_nft_score_model13.FAIL;
|
|
290
|
+
if (typeof nft.type !== "string") return import_crypto_nft_score_model13.FAIL;
|
|
328
291
|
const type = nft.type.toUpperCase();
|
|
329
|
-
if (type !== "ERC721" && type !== "ERC1155")
|
|
330
|
-
return import_crypto_nft_score_model13.FAIL;
|
|
292
|
+
if (type !== "ERC721" && type !== "ERC1155") return import_crypto_nft_score_model13.FAIL;
|
|
331
293
|
return import_crypto_nft_score_model13.PASS;
|
|
332
294
|
};
|
|
333
295
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Diviner.ts","../../src/lib/rating/criteria/scoring/contract.ts","../../src/lib/rating/criteria/scoring/metadata/animationUrl.ts","../../src/lib/rating/criteria/scoring/metadata/lib/urlHelpers.ts","../../src/lib/rating/criteria/scoring/metadata/attributes/evaluateAttributes.ts","../../src/lib/rating/criteria/scoring/metadata/backgroundColor.ts","../../src/lib/rating/criteria/scoring/metadata/description.ts","../../src/lib/rating/criteria/scoring/metadata/externalUrl.ts","../../src/lib/rating/criteria/scoring/metadata/image.ts","../../src/lib/rating/criteria/scoring/metadata/imageData.ts","../../src/lib/rating/criteria/scoring/metadata/name.ts","../../src/lib/rating/criteria/scoring/metadata/youtubeUrl.ts","../../src/lib/rating/criteria/scoring/supply.ts","../../src/lib/rating/criteria/scoring/tokenId.ts","../../src/lib/rating/criteria/scoring/type.ts","../../src/lib/rating/criteria/scoringCriteria.ts","../../src/lib/rating/analyzeNft.ts","../../src/Plugin.ts"],"sourcesContent":["export * from './Diviner'\nexport * from './lib'\nexport { NftScoreDivinerPlugin as default, NftScoreDivinerPlugin } from './Plugin'\n","import {\n isNftInfo,\n NftInfo,\n NftScore,\n NftScoreDivinerConfig,\n NftScoreDivinerConfigSchema,\n NftScoreSchema,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { AbstractDiviner } from '@xyo-network/diviner-abstract'\nimport { DivinerParams } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload, Schema } from '@xyo-network/payload-model'\n\nimport { analyzeNft, NftAnalysis } from './lib'\n\nexport type NftScoreDivinerParams = DivinerParams<AnyConfigSchema<NftScoreDivinerConfig>>\n\nconst toNftScorePayload = (nftInfo: NftInfo, scores: NftAnalysis): NftScore => {\n const { address, chainId, type } = nftInfo\n return { address, chainId, schema: NftScoreSchema, scores, type }\n}\n\nexport const isNftScore = (payload: Payload): payload is NftScore => payload.schema === NftScoreSchema\n\nexport class NftScoreDiviner<TParams extends NftScoreDivinerParams = NftScoreDivinerParams> extends AbstractDiviner<TParams> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, NftScoreDivinerConfigSchema]\n static override readonly defaultConfigSchema: Schema = NftScoreDivinerConfigSchema\n\n protected override divineHandler = async (payloads?: Payload[]): Promise<Payload[]> => {\n const nftInfos = payloads?.filter(isNftInfo) ?? []\n const results = await Promise.all(\n nftInfos.map<Promise<NftScore>>(async (nftInfo) => {\n const [score, sourceHash] = await Promise.all([\n // Analyze the NFT\n toNftScorePayload(nftInfo, await analyzeNft(nftInfo)),\n // Hash the source payload\n PayloadBuilder.dataHash(nftInfo),\n ])\n return { ...score, sources: [sourceHash] }\n }),\n )\n return results\n }\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\nimport { isAddress } from 'ethers'\n\nexport const scoreContractAddress: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.address) return FAIL\n if (typeof nft.address !== 'string') return FAIL\n if (!isAddress(nft.address)) return FAIL\n return PASS\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementPossible, incrementTotal, incrementTotalAndPossible, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl, isWeb3 } from './lib'\n\nexport const scoreNftAnimationUrl = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreAnimationUrl(nft.metadata?.animation_url)\n}\n\nexport const scoreAnimationUrl = (animation_url: unknown): ScaledScore => {\n const score: ScaledScore = [0, 0]\n if (animation_url === undefined || animation_url === null) return PASS\n incrementPossible(score)\n if (typeof animation_url !== 'string') return score\n incrementTotalAndPossible(score)\n if (!isValidUrl(animation_url)) return score\n incrementTotalAndPossible(score)\n if (!isSecure(animation_url)) return score\n incrementTotalAndPossible(score)\n if (!isWeb3(animation_url)) return score\n return incrementTotal(score)\n}\n","import { URL } from '@xylabs/url'\n\nexport const web3Protocols = ['ipfs:', 'ar:']\n\nexport const toUrl = (url?: string | null): URL | undefined => {\n if (!url) return undefined\n try {\n return new URL(url)\n } catch {\n return undefined\n }\n}\n\nexport const isValidUrl = (url?: string | null): boolean => toUrl(url) !== undefined\n// eslint-disable-next-line unicorn/prefer-includes\nexport const isWeb3 = (url?: string | null): boolean => web3Protocols.some((protocol) => protocol === toUrl(url)?.protocol)\nexport const isWeb2 = (url?: string | null): boolean => !isWeb3(url)\nexport const isSecure = (url?: string | null): boolean => isWeb3(url) || toUrl(url)?.protocol === 'https:'\n","import { NftAttribute, NftInfoFields, OpenSeaNftAttribute, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementPossible, incrementTotal, incrementTotalAndPossible, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nconst isDate = (value: unknown): value is Date => {\n if (isNumber(value)) {\n try {\n new Date(value)\n return true\n } catch {\n return false\n }\n }\n return false\n}\n\nconst isNumber = (value: unknown): value is number => typeof value === 'number'\n\nconst isPercentage = (value: unknown): boolean => isNumber(value) && value >= 0 && value <= 100\n\nconst isNonEmptyString = (value: unknown): value is string => typeof value === 'string' && value.length > 0\n\nconst isNonEmptyStringOrNumber = (value: unknown): value is string | number => value === 'number' || isNonEmptyString(value)\n\nexport const evaluateNftAttributes = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore =>\n nft?.metadata?.attributes ? evaluateAttributes(nft?.metadata?.attributes) : [0, 1]\n\nexport const evaluateAttributes = (attributes: NftAttribute[] | OpenSeaNftAttribute[] | unknown): ScaledScore => {\n if (!attributes || !Array.isArray(attributes) || attributes.length === 0) return [0, 1]\n const score: ScaledScore = [0, 0]\n for (const attribute of attributes) {\n const [attributeTotal, attributePossible] = evaluateAttribute(attribute)\n incrementTotalAndPossible(score, attributeTotal, attributePossible)\n }\n return [1, 1]\n}\n\nexport const evaluateAttribute = (attribute: OpenSeaNftAttribute): ScaledScore => {\n const score: ScaledScore = [0, 1]\n const max_value = attribute?.max_value\n const trait_type = attribute?.trait_type\n const value = attribute?.value\n\n // Validate trait_type & value\n if (!attribute || typeof attribute !== 'object' || !isNonEmptyString(trait_type) || !isNonEmptyStringOrNumber(value)) return score\n incrementTotal(score)\n\n // Validate display_type\n incrementPossible(score)\n if (validDisplayType(attribute)) incrementTotal(score)\n\n // Validate max_value\n if (max_value !== undefined) {\n incrementPossible(score)\n if (isNumber(max_value) && isNumber(value) && value <= max_value) incrementTotal(score)\n }\n\n return score\n}\n\nconst validDisplayType = (attribute: OpenSeaNftAttribute): boolean => {\n switch (attribute?.display_type) {\n case 'number':\n case 'boost_number': {\n if (isNumber(attribute?.value)) return true\n break\n }\n case 'boost_percentage': {\n if (isPercentage(attribute?.value)) return true\n break\n }\n case 'date': {\n if (isDate(attribute?.value)) return true\n break\n }\n case 'string':\n case undefined: {\n if (isNonEmptyString(attribute?.value)) return true\n break\n }\n default: {\n break\n }\n }\n return false\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementPossible, incrementTotal, incrementTotalAndPossible, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nconst isHexColor = /^[\\da-f]{6}$/i\n\nexport const scoreNftBackgroundColor = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreBackgroundColor(nft.metadata?.background_color)\n}\n\nexport const scoreBackgroundColor = (background_color: unknown): ScaledScore => {\n const score: ScaledScore = [0, 0]\n if (background_color === undefined || background_color === null) return PASS\n incrementPossible(score)\n if (typeof background_color !== 'string') return score\n incrementTotalAndPossible(score)\n if (!isHexColor.test(background_color.toUpperCase())) return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreNftDescription = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreDescription(nft.metadata?.description)\n}\n\nexport const scoreDescription = (description: unknown): ScaledScore => {\n const score: ScaledScore = [0, 1]\n if (!description || typeof description !== 'string') return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl } from './lib'\n\nexport const scoreNftExternalUrl = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreExternalUrl(nft?.metadata?.external_url)\n}\nexport const scoreExternalUrl = (external_url: unknown): ScaledScore => {\n const score: ScaledScore = [0, 2]\n if (external_url === undefined || external_url === null || typeof external_url !== 'string' || !isValidUrl(external_url)) return score\n incrementTotal(score)\n if (!isSecure(external_url)) return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl, isWeb3 } from './lib'\n\nconst MaxPossibleImageScore = 3\n\nexport const scoreNftImage = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n // If there's no image data\n if (nft?.metadata?.image) {\n return scoreImage(nft.metadata?.image)\n } else {\n // but there is image data, skip this scoring criteria, otherwise fail it completely\n return nft.metadata?.image_data ? PASS : [0, MaxPossibleImageScore]\n }\n}\n\nexport const scoreImage = (image: unknown): ScaledScore => {\n const score: ScaledScore = [0, MaxPossibleImageScore]\n if (!image || typeof image !== 'string' || !isValidUrl(image)) return score\n incrementTotal(score)\n if (!isSecure(image)) return score\n incrementTotal(score)\n if (!isWeb3(image)) return score\n incrementTotal(score)\n return score\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\nimport { parse } from 'svg-parser'\n\nconst MaxPossibleImageDataScore = 1\n\n// NOTE: There is probably a deeper check we can do\n// here, but this is a good start\nconst isValidImageData = (image_data: string): boolean => {\n // If it doesn't start with an svg tag, it's not an svg\n if (!image_data.startsWith('<svg')) return false\n try {\n // If it can't be parsed, it's not an svg\n parse(image_data)\n return true\n } catch {\n return false\n }\n}\n\nexport const scoreNftImageData = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n // If there's no image data\n if (nft?.metadata?.image_data) {\n return scoreImageData(nft.metadata?.image_data)\n } else {\n // but there is an image, skip this scoring criteria, otherwise fail it completely\n return nft.metadata?.image ? PASS : [0, MaxPossibleImageDataScore]\n }\n}\n\nexport const scoreImageData = (image_data: unknown): ScaledScore => {\n return !image_data || typeof image_data !== 'string' || !isValidImageData(image_data) ?\n [0, MaxPossibleImageDataScore]\n : [MaxPossibleImageDataScore, MaxPossibleImageDataScore]\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreNftName = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreName(nft.metadata?.name)\n}\nexport const scoreName = (name: unknown): ScaledScore => {\n const score: ScaledScore = [0, 1]\n if (!name || typeof name !== 'string') return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl } from './lib'\n\nexport const scoreNftYoutubeUrl = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreYoutubeUrl(nft?.metadata?.youtube_url)\n}\nexport const scoreYoutubeUrl = (youtube_url: unknown): ScaledScore => {\n if (youtube_url === undefined || youtube_url === null) return PASS\n const score: ScaledScore = [0, 2]\n if (typeof youtube_url !== 'string' || !isValidUrl(youtube_url)) return score\n incrementTotal(score)\n if (!isSecure(youtube_url)) return score\n return incrementTotal(score)\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreSupply: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.supply) return FAIL\n if (typeof nft.supply !== 'string') return FAIL\n try {\n return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? PASS : FAIL\n } catch {\n return FAIL\n }\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\n\n/**\n * Callers SHALL NOT assume that ID numbers have any specific pattern to them, and\n * MUST treat the ID as a \"black box\"\n * @param nft\n * @returns\n */\nexport const scoreTokenId: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.tokenId) return FAIL\n if (typeof nft.tokenId !== 'string') return FAIL\n try {\n return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? PASS : FAIL\n } catch {\n return FAIL\n }\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreType: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.type) return FAIL\n if (typeof nft.type !== 'string') return FAIL\n const type = nft.type.toUpperCase()\n if (type !== 'ERC721' && type !== 'ERC1155') return FAIL\n return PASS\n}\n","import {\n evaluateNftAttributes,\n scoreContractAddress,\n scoreNftAnimationUrl,\n scoreNftBackgroundColor,\n scoreNftDescription,\n scoreNftExternalUrl,\n scoreNftImage,\n scoreNftImageData,\n scoreNftName,\n scoreNftYoutubeUrl,\n scoreSupply,\n scoreTokenId,\n scoreType,\n} from './scoring'\n\nconst attributesScoringCriteria = {\n Attributes: { score: evaluateNftAttributes, weight: 1 },\n}\n\nconst metadataScoringCriteria = {\n 'Animation URL': { score: scoreNftAnimationUrl, weight: 1 },\n 'Background Color': { score: scoreNftBackgroundColor, weight: 1 },\n Description: { score: scoreNftDescription, weight: 1 },\n 'External Url': { score: scoreNftExternalUrl, weight: 1 },\n Image: { score: scoreNftImage, weight: 1 },\n 'Image Data': { score: scoreNftImageData, weight: 1 },\n Name: { score: scoreNftName, weight: 1 },\n 'YouTube URL': { score: scoreNftYoutubeUrl, weight: 1 },\n ...attributesScoringCriteria,\n}\n\nexport const scoringCriteria = {\n 'Contract Address': { score: scoreContractAddress, weight: 1 },\n Supply: { score: scoreSupply, weight: 1 },\n 'Token Id': { score: scoreTokenId, weight: 1 },\n Type: { score: scoreType, weight: 1 },\n ...metadataScoringCriteria,\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { Score } from '@xyo-network/crypto-nft-score-model'\n\nimport { scoringCriteria } from './criteria'\n\nexport type ScoringCriteriaKey = keyof typeof scoringCriteria & PropertyKey\n\nexport type NftAnalysis = {\n [key in ScoringCriteriaKey]: Score\n}\n\nexport const analyzeNft = async (\n /**\n * The NFT to evaluate\n */\n nft: NftInfoFields,\n): Promise<NftAnalysis> => {\n const result = Object.fromEntries(\n await Promise.all(\n Object.entries(scoringCriteria).map(async ([key, { score, weight }]) => {\n const rawScore = await score(nft)\n const weighted = rawScore.map((v) => v * weight) as Score\n return [key, weighted] as const\n }),\n ),\n ) as NftAnalysis\n return result\n}\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetDivinerPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { NftScoreDiviner } from './Diviner'\n\nexport const NftScoreDivinerPlugin = () =>\n createPayloadSetDivinerPlugin<NftScoreDiviner>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n diviner: async (params) => {\n const result = await NftScoreDiviner.create(params)\n return result\n },\n },\n )\n"],"mappings":"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","names":["import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_payload_plugin"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Diviner.ts","../../src/lib/rating/criteria/scoring/contract.ts","../../src/lib/rating/criteria/scoring/metadata/animationUrl.ts","../../src/lib/rating/criteria/scoring/metadata/lib/urlHelpers.ts","../../src/lib/rating/criteria/scoring/metadata/attributes/evaluateAttributes.ts","../../src/lib/rating/criteria/scoring/metadata/backgroundColor.ts","../../src/lib/rating/criteria/scoring/metadata/description.ts","../../src/lib/rating/criteria/scoring/metadata/externalUrl.ts","../../src/lib/rating/criteria/scoring/metadata/image.ts","../../src/lib/rating/criteria/scoring/metadata/imageData.ts","../../src/lib/rating/criteria/scoring/metadata/name.ts","../../src/lib/rating/criteria/scoring/metadata/youtubeUrl.ts","../../src/lib/rating/criteria/scoring/supply.ts","../../src/lib/rating/criteria/scoring/tokenId.ts","../../src/lib/rating/criteria/scoring/type.ts","../../src/lib/rating/criteria/scoringCriteria.ts","../../src/lib/rating/analyzeNft.ts","../../src/Plugin.ts"],"sourcesContent":["export * from './Diviner'\nexport * from './lib'\nexport { NftScoreDivinerPlugin as default, NftScoreDivinerPlugin } from './Plugin'\n","import {\n isNftInfo,\n NftInfo,\n NftScore,\n NftScoreDivinerConfig,\n NftScoreDivinerConfigSchema,\n NftScoreSchema,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { AbstractDiviner } from '@xyo-network/diviner-abstract'\nimport { DivinerParams } from '@xyo-network/diviner-model'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Payload, Schema } from '@xyo-network/payload-model'\n\nimport { analyzeNft, NftAnalysis } from './lib'\n\nexport type NftScoreDivinerParams = DivinerParams<AnyConfigSchema<NftScoreDivinerConfig>>\n\nconst toNftScorePayload = (nftInfo: NftInfo, scores: NftAnalysis): NftScore => {\n const { address, chainId, type } = nftInfo\n return { address, chainId, schema: NftScoreSchema, scores, type }\n}\n\nexport const isNftScore = (payload: Payload): payload is NftScore => payload.schema === NftScoreSchema\n\nexport class NftScoreDiviner<TParams extends NftScoreDivinerParams = NftScoreDivinerParams> extends AbstractDiviner<TParams> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, NftScoreDivinerConfigSchema]\n static override readonly defaultConfigSchema: Schema = NftScoreDivinerConfigSchema\n\n protected override divineHandler = async (payloads?: Payload[]): Promise<Payload[]> => {\n const nftInfos = payloads?.filter(isNftInfo) ?? []\n const results = await Promise.all(\n nftInfos.map<Promise<NftScore>>(async (nftInfo) => {\n const [score, sourceHash] = await Promise.all([\n // Analyze the NFT\n toNftScorePayload(nftInfo, await analyzeNft(nftInfo)),\n // Hash the source payload\n PayloadBuilder.dataHash(nftInfo),\n ])\n return { ...score, sources: [sourceHash] }\n }),\n )\n return results\n }\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\nimport { isAddress } from 'ethers'\n\nexport const scoreContractAddress: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.address) return FAIL\n if (typeof nft.address !== 'string') return FAIL\n if (!isAddress(nft.address)) return FAIL\n return PASS\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementPossible, incrementTotal, incrementTotalAndPossible, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl, isWeb3 } from './lib'\n\nexport const scoreNftAnimationUrl = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreAnimationUrl(nft.metadata?.animation_url)\n}\n\nexport const scoreAnimationUrl = (animation_url: unknown): ScaledScore => {\n const score: ScaledScore = [0, 0]\n if (animation_url === undefined || animation_url === null) return PASS\n incrementPossible(score)\n if (typeof animation_url !== 'string') return score\n incrementTotalAndPossible(score)\n if (!isValidUrl(animation_url)) return score\n incrementTotalAndPossible(score)\n if (!isSecure(animation_url)) return score\n incrementTotalAndPossible(score)\n if (!isWeb3(animation_url)) return score\n return incrementTotal(score)\n}\n","import { URL } from '@xylabs/url'\n\nexport const web3Protocols = ['ipfs:', 'ar:']\n\nexport const toUrl = (url?: string | null): URL | undefined => {\n if (!url) return undefined\n try {\n return new URL(url)\n } catch {\n return undefined\n }\n}\n\nexport const isValidUrl = (url?: string | null): boolean => toUrl(url) !== undefined\n// eslint-disable-next-line unicorn/prefer-includes\nexport const isWeb3 = (url?: string | null): boolean => web3Protocols.some((protocol) => protocol === toUrl(url)?.protocol)\nexport const isWeb2 = (url?: string | null): boolean => !isWeb3(url)\nexport const isSecure = (url?: string | null): boolean => isWeb3(url) || toUrl(url)?.protocol === 'https:'\n","import { NftAttribute, NftInfoFields, OpenSeaNftAttribute, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementPossible, incrementTotal, incrementTotalAndPossible, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nconst isDate = (value: unknown): value is Date => {\n if (isNumber(value)) {\n try {\n new Date(value)\n return true\n } catch {\n return false\n }\n }\n return false\n}\n\nconst isNumber = (value: unknown): value is number => typeof value === 'number'\n\nconst isPercentage = (value: unknown): boolean => isNumber(value) && value >= 0 && value <= 100\n\nconst isNonEmptyString = (value: unknown): value is string => typeof value === 'string' && value.length > 0\n\nconst isNonEmptyStringOrNumber = (value: unknown): value is string | number => value === 'number' || isNonEmptyString(value)\n\nexport const evaluateNftAttributes = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore =>\n nft?.metadata?.attributes ? evaluateAttributes(nft?.metadata?.attributes) : [0, 1]\n\nexport const evaluateAttributes = (attributes: NftAttribute[] | OpenSeaNftAttribute[] | unknown): ScaledScore => {\n if (!attributes || !Array.isArray(attributes) || attributes.length === 0) return [0, 1]\n const score: ScaledScore = [0, 0]\n for (const attribute of attributes) {\n const [attributeTotal, attributePossible] = evaluateAttribute(attribute)\n incrementTotalAndPossible(score, attributeTotal, attributePossible)\n }\n return [1, 1]\n}\n\nexport const evaluateAttribute = (attribute: OpenSeaNftAttribute): ScaledScore => {\n const score: ScaledScore = [0, 1]\n const max_value = attribute?.max_value\n const trait_type = attribute?.trait_type\n const value = attribute?.value\n\n // Validate trait_type & value\n if (!attribute || typeof attribute !== 'object' || !isNonEmptyString(trait_type) || !isNonEmptyStringOrNumber(value)) return score\n incrementTotal(score)\n\n // Validate display_type\n incrementPossible(score)\n if (validDisplayType(attribute)) incrementTotal(score)\n\n // Validate max_value\n if (max_value !== undefined) {\n incrementPossible(score)\n if (isNumber(max_value) && isNumber(value) && value <= max_value) incrementTotal(score)\n }\n\n return score\n}\n\nconst validDisplayType = (attribute: OpenSeaNftAttribute): boolean => {\n switch (attribute?.display_type) {\n case 'number':\n case 'boost_number': {\n if (isNumber(attribute?.value)) return true\n break\n }\n case 'boost_percentage': {\n if (isPercentage(attribute?.value)) return true\n break\n }\n case 'date': {\n if (isDate(attribute?.value)) return true\n break\n }\n case 'string':\n case undefined: {\n if (isNonEmptyString(attribute?.value)) return true\n break\n }\n default: {\n break\n }\n }\n return false\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementPossible, incrementTotal, incrementTotalAndPossible, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nconst isHexColor = /^[\\da-f]{6}$/i\n\nexport const scoreNftBackgroundColor = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreBackgroundColor(nft.metadata?.background_color)\n}\n\nexport const scoreBackgroundColor = (background_color: unknown): ScaledScore => {\n const score: ScaledScore = [0, 0]\n if (background_color === undefined || background_color === null) return PASS\n incrementPossible(score)\n if (typeof background_color !== 'string') return score\n incrementTotalAndPossible(score)\n if (!isHexColor.test(background_color.toUpperCase())) return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreNftDescription = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreDescription(nft.metadata?.description)\n}\n\nexport const scoreDescription = (description: unknown): ScaledScore => {\n const score: ScaledScore = [0, 1]\n if (!description || typeof description !== 'string') return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl } from './lib'\n\nexport const scoreNftExternalUrl = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreExternalUrl(nft?.metadata?.external_url)\n}\nexport const scoreExternalUrl = (external_url: unknown): ScaledScore => {\n const score: ScaledScore = [0, 2]\n if (external_url === undefined || external_url === null || typeof external_url !== 'string' || !isValidUrl(external_url)) return score\n incrementTotal(score)\n if (!isSecure(external_url)) return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl, isWeb3 } from './lib'\n\nconst MaxPossibleImageScore = 3\n\nexport const scoreNftImage = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n // If there's no image data\n if (nft?.metadata?.image) {\n return scoreImage(nft.metadata?.image)\n } else {\n // but there is image data, skip this scoring criteria, otherwise fail it completely\n return nft.metadata?.image_data ? PASS : [0, MaxPossibleImageScore]\n }\n}\n\nexport const scoreImage = (image: unknown): ScaledScore => {\n const score: ScaledScore = [0, MaxPossibleImageScore]\n if (!image || typeof image !== 'string' || !isValidUrl(image)) return score\n incrementTotal(score)\n if (!isSecure(image)) return score\n incrementTotal(score)\n if (!isWeb3(image)) return score\n incrementTotal(score)\n return score\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\nimport { parse } from 'svg-parser'\n\nconst MaxPossibleImageDataScore = 1\n\n// NOTE: There is probably a deeper check we can do\n// here, but this is a good start\nconst isValidImageData = (image_data: string): boolean => {\n // If it doesn't start with an svg tag, it's not an svg\n if (!image_data.startsWith('<svg')) return false\n try {\n // If it can't be parsed, it's not an svg\n parse(image_data)\n return true\n } catch {\n return false\n }\n}\n\nexport const scoreNftImageData = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n // If there's no image data\n if (nft?.metadata?.image_data) {\n return scoreImageData(nft.metadata?.image_data)\n } else {\n // but there is an image, skip this scoring criteria, otherwise fail it completely\n return nft.metadata?.image ? PASS : [0, MaxPossibleImageDataScore]\n }\n}\n\nexport const scoreImageData = (image_data: unknown): ScaledScore => {\n return !image_data || typeof image_data !== 'string' || !isValidImageData(image_data) ?\n [0, MaxPossibleImageDataScore]\n : [MaxPossibleImageDataScore, MaxPossibleImageDataScore]\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreNftName = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreName(nft.metadata?.name)\n}\nexport const scoreName = (name: unknown): ScaledScore => {\n const score: ScaledScore = [0, 1]\n if (!name || typeof name !== 'string') return score\n return incrementTotal(score)\n}\n","import { NftInfoFields, OpenSeaNftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { incrementTotal, PASS, ScaledScore } from '@xyo-network/crypto-nft-score-model'\n\nimport { isSecure, isValidUrl } from './lib'\n\nexport const scoreNftYoutubeUrl = (nft: NftInfoFields | OpenSeaNftInfoFields): ScaledScore => {\n return scoreYoutubeUrl(nft?.metadata?.youtube_url)\n}\nexport const scoreYoutubeUrl = (youtube_url: unknown): ScaledScore => {\n if (youtube_url === undefined || youtube_url === null) return PASS\n const score: ScaledScore = [0, 2]\n if (typeof youtube_url !== 'string' || !isValidUrl(youtube_url)) return score\n incrementTotal(score)\n if (!isSecure(youtube_url)) return score\n return incrementTotal(score)\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreSupply: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.supply) return FAIL\n if (typeof nft.supply !== 'string') return FAIL\n try {\n return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? PASS : FAIL\n } catch {\n return FAIL\n }\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\n\n/**\n * Callers SHALL NOT assume that ID numbers have any specific pattern to them, and\n * MUST treat the ID as a \"black box\"\n * @param nft\n * @returns\n */\nexport const scoreTokenId: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.tokenId) return FAIL\n if (typeof nft.tokenId !== 'string') return FAIL\n try {\n return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? PASS : FAIL\n } catch {\n return FAIL\n }\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { FAIL, PASS, PassFailScoringFunction } from '@xyo-network/crypto-nft-score-model'\n\nexport const scoreType: PassFailScoringFunction<NftInfoFields> = (nft: NftInfoFields) => {\n if (!nft.type) return FAIL\n if (typeof nft.type !== 'string') return FAIL\n const type = nft.type.toUpperCase()\n if (type !== 'ERC721' && type !== 'ERC1155') return FAIL\n return PASS\n}\n","import {\n evaluateNftAttributes,\n scoreContractAddress,\n scoreNftAnimationUrl,\n scoreNftBackgroundColor,\n scoreNftDescription,\n scoreNftExternalUrl,\n scoreNftImage,\n scoreNftImageData,\n scoreNftName,\n scoreNftYoutubeUrl,\n scoreSupply,\n scoreTokenId,\n scoreType,\n} from './scoring'\n\nconst attributesScoringCriteria = {\n Attributes: { score: evaluateNftAttributes, weight: 1 },\n}\n\nconst metadataScoringCriteria = {\n 'Animation URL': { score: scoreNftAnimationUrl, weight: 1 },\n 'Background Color': { score: scoreNftBackgroundColor, weight: 1 },\n Description: { score: scoreNftDescription, weight: 1 },\n 'External Url': { score: scoreNftExternalUrl, weight: 1 },\n Image: { score: scoreNftImage, weight: 1 },\n 'Image Data': { score: scoreNftImageData, weight: 1 },\n Name: { score: scoreNftName, weight: 1 },\n 'YouTube URL': { score: scoreNftYoutubeUrl, weight: 1 },\n ...attributesScoringCriteria,\n}\n\nexport const scoringCriteria = {\n 'Contract Address': { score: scoreContractAddress, weight: 1 },\n Supply: { score: scoreSupply, weight: 1 },\n 'Token Id': { score: scoreTokenId, weight: 1 },\n Type: { score: scoreType, weight: 1 },\n ...metadataScoringCriteria,\n}\n","import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { Score } from '@xyo-network/crypto-nft-score-model'\n\nimport { scoringCriteria } from './criteria'\n\nexport type ScoringCriteriaKey = keyof typeof scoringCriteria & PropertyKey\n\nexport type NftAnalysis = {\n [key in ScoringCriteriaKey]: Score\n}\n\nexport const analyzeNft = async (\n /**\n * The NFT to evaluate\n */\n nft: NftInfoFields,\n): Promise<NftAnalysis> => {\n const result = Object.fromEntries(\n await Promise.all(\n Object.entries(scoringCriteria).map(async ([key, { score, weight }]) => {\n const rawScore = await score(nft)\n const weighted = rawScore.map((v) => v * weight) as Score\n return [key, weighted] as const\n }),\n ),\n ) as NftAnalysis\n return result\n}\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetDivinerPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { NftScoreDiviner } from './Diviner'\n\nexport const NftScoreDivinerPlugin = () =>\n createPayloadSetDivinerPlugin<NftScoreDiviner>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n diviner: async (params) => {\n const result = await NftScoreDiviner.create(params)\n return result\n },\n },\n )\n"],"mappings":"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","names":["import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_score_model","import_crypto_nft_payload_plugin"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -11,12 +11,9 @@ import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
|
11
11
|
import { FAIL, PASS } from "@xyo-network/crypto-nft-score-model";
|
|
12
12
|
import { isAddress } from "ethers";
|
|
13
13
|
var scoreContractAddress = (nft) => {
|
|
14
|
-
if (!nft.address)
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
return FAIL;
|
|
18
|
-
if (!isAddress(nft.address))
|
|
19
|
-
return FAIL;
|
|
14
|
+
if (!nft.address) return FAIL;
|
|
15
|
+
if (typeof nft.address !== "string") return FAIL;
|
|
16
|
+
if (!isAddress(nft.address)) return FAIL;
|
|
20
17
|
return PASS;
|
|
21
18
|
};
|
|
22
19
|
|
|
@@ -27,8 +24,7 @@ import { incrementPossible, incrementTotal, incrementTotalAndPossible, PASS as P
|
|
|
27
24
|
import { URL } from "@xylabs/url";
|
|
28
25
|
var web3Protocols = ["ipfs:", "ar:"];
|
|
29
26
|
var toUrl = (url) => {
|
|
30
|
-
if (!url)
|
|
31
|
-
return void 0;
|
|
27
|
+
if (!url) return void 0;
|
|
32
28
|
try {
|
|
33
29
|
return new URL(url);
|
|
34
30
|
} catch {
|
|
@@ -45,20 +41,15 @@ var scoreNftAnimationUrl = (nft) => {
|
|
|
45
41
|
};
|
|
46
42
|
var scoreAnimationUrl = (animation_url) => {
|
|
47
43
|
const score = [0, 0];
|
|
48
|
-
if (animation_url === void 0 || animation_url === null)
|
|
49
|
-
return PASS2;
|
|
44
|
+
if (animation_url === void 0 || animation_url === null) return PASS2;
|
|
50
45
|
incrementPossible(score);
|
|
51
|
-
if (typeof animation_url !== "string")
|
|
52
|
-
return score;
|
|
46
|
+
if (typeof animation_url !== "string") return score;
|
|
53
47
|
incrementTotalAndPossible(score);
|
|
54
|
-
if (!isValidUrl(animation_url))
|
|
55
|
-
return score;
|
|
48
|
+
if (!isValidUrl(animation_url)) return score;
|
|
56
49
|
incrementTotalAndPossible(score);
|
|
57
|
-
if (!isSecure(animation_url))
|
|
58
|
-
return score;
|
|
50
|
+
if (!isSecure(animation_url)) return score;
|
|
59
51
|
incrementTotalAndPossible(score);
|
|
60
|
-
if (!isWeb3(animation_url))
|
|
61
|
-
return score;
|
|
52
|
+
if (!isWeb3(animation_url)) return score;
|
|
62
53
|
return incrementTotal(score);
|
|
63
54
|
};
|
|
64
55
|
|
|
@@ -81,8 +72,7 @@ var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
|
81
72
|
var isNonEmptyStringOrNumber = (value) => value === "number" || isNonEmptyString(value);
|
|
82
73
|
var evaluateNftAttributes = (nft) => nft?.metadata?.attributes ? evaluateAttributes(nft?.metadata?.attributes) : [0, 1];
|
|
83
74
|
var evaluateAttributes = (attributes) => {
|
|
84
|
-
if (!attributes || !Array.isArray(attributes) || attributes.length === 0)
|
|
85
|
-
return [0, 1];
|
|
75
|
+
if (!attributes || !Array.isArray(attributes) || attributes.length === 0) return [0, 1];
|
|
86
76
|
const score = [0, 0];
|
|
87
77
|
for (const attribute of attributes) {
|
|
88
78
|
const [attributeTotal, attributePossible] = evaluateAttribute(attribute);
|
|
@@ -95,16 +85,13 @@ var evaluateAttribute = (attribute) => {
|
|
|
95
85
|
const max_value = attribute?.max_value;
|
|
96
86
|
const trait_type = attribute?.trait_type;
|
|
97
87
|
const value = attribute?.value;
|
|
98
|
-
if (!attribute || typeof attribute !== "object" || !isNonEmptyString(trait_type) || !isNonEmptyStringOrNumber(value))
|
|
99
|
-
return score;
|
|
88
|
+
if (!attribute || typeof attribute !== "object" || !isNonEmptyString(trait_type) || !isNonEmptyStringOrNumber(value)) return score;
|
|
100
89
|
incrementTotal2(score);
|
|
101
90
|
incrementPossible2(score);
|
|
102
|
-
if (validDisplayType(attribute))
|
|
103
|
-
incrementTotal2(score);
|
|
91
|
+
if (validDisplayType(attribute)) incrementTotal2(score);
|
|
104
92
|
if (max_value !== void 0) {
|
|
105
93
|
incrementPossible2(score);
|
|
106
|
-
if (isNumber(max_value) && isNumber(value) && value <= max_value)
|
|
107
|
-
incrementTotal2(score);
|
|
94
|
+
if (isNumber(max_value) && isNumber(value) && value <= max_value) incrementTotal2(score);
|
|
108
95
|
}
|
|
109
96
|
return score;
|
|
110
97
|
};
|
|
@@ -112,24 +99,20 @@ var validDisplayType = (attribute) => {
|
|
|
112
99
|
switch (attribute?.display_type) {
|
|
113
100
|
case "number":
|
|
114
101
|
case "boost_number": {
|
|
115
|
-
if (isNumber(attribute?.value))
|
|
116
|
-
return true;
|
|
102
|
+
if (isNumber(attribute?.value)) return true;
|
|
117
103
|
break;
|
|
118
104
|
}
|
|
119
105
|
case "boost_percentage": {
|
|
120
|
-
if (isPercentage(attribute?.value))
|
|
121
|
-
return true;
|
|
106
|
+
if (isPercentage(attribute?.value)) return true;
|
|
122
107
|
break;
|
|
123
108
|
}
|
|
124
109
|
case "date": {
|
|
125
|
-
if (isDate(attribute?.value))
|
|
126
|
-
return true;
|
|
110
|
+
if (isDate(attribute?.value)) return true;
|
|
127
111
|
break;
|
|
128
112
|
}
|
|
129
113
|
case "string":
|
|
130
114
|
case void 0: {
|
|
131
|
-
if (isNonEmptyString(attribute?.value))
|
|
132
|
-
return true;
|
|
115
|
+
if (isNonEmptyString(attribute?.value)) return true;
|
|
133
116
|
break;
|
|
134
117
|
}
|
|
135
118
|
default: {
|
|
@@ -147,14 +130,11 @@ var scoreNftBackgroundColor = (nft) => {
|
|
|
147
130
|
};
|
|
148
131
|
var scoreBackgroundColor = (background_color) => {
|
|
149
132
|
const score = [0, 0];
|
|
150
|
-
if (background_color === void 0 || background_color === null)
|
|
151
|
-
return PASS3;
|
|
133
|
+
if (background_color === void 0 || background_color === null) return PASS3;
|
|
152
134
|
incrementPossible3(score);
|
|
153
|
-
if (typeof background_color !== "string")
|
|
154
|
-
return score;
|
|
135
|
+
if (typeof background_color !== "string") return score;
|
|
155
136
|
incrementTotalAndPossible3(score);
|
|
156
|
-
if (!isHexColor.test(background_color.toUpperCase()))
|
|
157
|
-
return score;
|
|
137
|
+
if (!isHexColor.test(background_color.toUpperCase())) return score;
|
|
158
138
|
return incrementTotal3(score);
|
|
159
139
|
};
|
|
160
140
|
|
|
@@ -165,8 +145,7 @@ var scoreNftDescription = (nft) => {
|
|
|
165
145
|
};
|
|
166
146
|
var scoreDescription = (description) => {
|
|
167
147
|
const score = [0, 1];
|
|
168
|
-
if (!description || typeof description !== "string")
|
|
169
|
-
return score;
|
|
148
|
+
if (!description || typeof description !== "string") return score;
|
|
170
149
|
return incrementTotal4(score);
|
|
171
150
|
};
|
|
172
151
|
|
|
@@ -177,11 +156,9 @@ var scoreNftExternalUrl = (nft) => {
|
|
|
177
156
|
};
|
|
178
157
|
var scoreExternalUrl = (external_url) => {
|
|
179
158
|
const score = [0, 2];
|
|
180
|
-
if (external_url === void 0 || external_url === null || typeof external_url !== "string" || !isValidUrl(external_url))
|
|
181
|
-
return score;
|
|
159
|
+
if (external_url === void 0 || external_url === null || typeof external_url !== "string" || !isValidUrl(external_url)) return score;
|
|
182
160
|
incrementTotal5(score);
|
|
183
|
-
if (!isSecure(external_url))
|
|
184
|
-
return score;
|
|
161
|
+
if (!isSecure(external_url)) return score;
|
|
185
162
|
return incrementTotal5(score);
|
|
186
163
|
};
|
|
187
164
|
|
|
@@ -197,14 +174,11 @@ var scoreNftImage = (nft) => {
|
|
|
197
174
|
};
|
|
198
175
|
var scoreImage = (image) => {
|
|
199
176
|
const score = [0, MaxPossibleImageScore];
|
|
200
|
-
if (!image || typeof image !== "string" || !isValidUrl(image))
|
|
201
|
-
return score;
|
|
177
|
+
if (!image || typeof image !== "string" || !isValidUrl(image)) return score;
|
|
202
178
|
incrementTotal6(score);
|
|
203
|
-
if (!isSecure(image))
|
|
204
|
-
return score;
|
|
179
|
+
if (!isSecure(image)) return score;
|
|
205
180
|
incrementTotal6(score);
|
|
206
|
-
if (!isWeb3(image))
|
|
207
|
-
return score;
|
|
181
|
+
if (!isWeb3(image)) return score;
|
|
208
182
|
incrementTotal6(score);
|
|
209
183
|
return score;
|
|
210
184
|
};
|
|
@@ -214,8 +188,7 @@ import { PASS as PASS5 } from "@xyo-network/crypto-nft-score-model";
|
|
|
214
188
|
import { parse } from "svg-parser";
|
|
215
189
|
var MaxPossibleImageDataScore = 1;
|
|
216
190
|
var isValidImageData = (image_data) => {
|
|
217
|
-
if (!image_data.startsWith("<svg"))
|
|
218
|
-
return false;
|
|
191
|
+
if (!image_data.startsWith("<svg")) return false;
|
|
219
192
|
try {
|
|
220
193
|
parse(image_data);
|
|
221
194
|
return true;
|
|
@@ -241,8 +214,7 @@ var scoreNftName = (nft) => {
|
|
|
241
214
|
};
|
|
242
215
|
var scoreName = (name) => {
|
|
243
216
|
const score = [0, 1];
|
|
244
|
-
if (!name || typeof name !== "string")
|
|
245
|
-
return score;
|
|
217
|
+
if (!name || typeof name !== "string") return score;
|
|
246
218
|
return incrementTotal7(score);
|
|
247
219
|
};
|
|
248
220
|
|
|
@@ -252,24 +224,19 @@ var scoreNftYoutubeUrl = (nft) => {
|
|
|
252
224
|
return scoreYoutubeUrl(nft?.metadata?.youtube_url);
|
|
253
225
|
};
|
|
254
226
|
var scoreYoutubeUrl = (youtube_url) => {
|
|
255
|
-
if (youtube_url === void 0 || youtube_url === null)
|
|
256
|
-
return PASS6;
|
|
227
|
+
if (youtube_url === void 0 || youtube_url === null) return PASS6;
|
|
257
228
|
const score = [0, 2];
|
|
258
|
-
if (typeof youtube_url !== "string" || !isValidUrl(youtube_url))
|
|
259
|
-
return score;
|
|
229
|
+
if (typeof youtube_url !== "string" || !isValidUrl(youtube_url)) return score;
|
|
260
230
|
incrementTotal8(score);
|
|
261
|
-
if (!isSecure(youtube_url))
|
|
262
|
-
return score;
|
|
231
|
+
if (!isSecure(youtube_url)) return score;
|
|
263
232
|
return incrementTotal8(score);
|
|
264
233
|
};
|
|
265
234
|
|
|
266
235
|
// src/lib/rating/criteria/scoring/supply.ts
|
|
267
236
|
import { FAIL as FAIL2, PASS as PASS7 } from "@xyo-network/crypto-nft-score-model";
|
|
268
237
|
var scoreSupply = (nft) => {
|
|
269
|
-
if (!nft.supply)
|
|
270
|
-
|
|
271
|
-
if (typeof nft.supply !== "string")
|
|
272
|
-
return FAIL2;
|
|
238
|
+
if (!nft.supply) return FAIL2;
|
|
239
|
+
if (typeof nft.supply !== "string") return FAIL2;
|
|
273
240
|
try {
|
|
274
241
|
return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? PASS7 : FAIL2;
|
|
275
242
|
} catch {
|
|
@@ -280,10 +247,8 @@ var scoreSupply = (nft) => {
|
|
|
280
247
|
// src/lib/rating/criteria/scoring/tokenId.ts
|
|
281
248
|
import { FAIL as FAIL3, PASS as PASS8 } from "@xyo-network/crypto-nft-score-model";
|
|
282
249
|
var scoreTokenId = (nft) => {
|
|
283
|
-
if (!nft.tokenId)
|
|
284
|
-
|
|
285
|
-
if (typeof nft.tokenId !== "string")
|
|
286
|
-
return FAIL3;
|
|
250
|
+
if (!nft.tokenId) return FAIL3;
|
|
251
|
+
if (typeof nft.tokenId !== "string") return FAIL3;
|
|
287
252
|
try {
|
|
288
253
|
return BigInt(nft.tokenId) >= 0n && BigInt(nft.tokenId) < 2n ** 256n ? PASS8 : FAIL3;
|
|
289
254
|
} catch {
|
|
@@ -294,13 +259,10 @@ var scoreTokenId = (nft) => {
|
|
|
294
259
|
// src/lib/rating/criteria/scoring/type.ts
|
|
295
260
|
import { FAIL as FAIL4, PASS as PASS9 } from "@xyo-network/crypto-nft-score-model";
|
|
296
261
|
var scoreType = (nft) => {
|
|
297
|
-
if (!nft.type)
|
|
298
|
-
|
|
299
|
-
if (typeof nft.type !== "string")
|
|
300
|
-
return FAIL4;
|
|
262
|
+
if (!nft.type) return FAIL4;
|
|
263
|
+
if (typeof nft.type !== "string") return FAIL4;
|
|
301
264
|
const type = nft.type.toUpperCase();
|
|
302
|
-
if (type !== "ERC721" && type !== "ERC1155")
|
|
303
|
-
return FAIL4;
|
|
265
|
+
if (type !== "ERC721" && type !== "ERC1155") return FAIL4;
|
|
304
266
|
return PASS9;
|
|
305
267
|
};
|
|
306
268
|
|