@xyo-network/crypto-nft-diviner-score-plugin 4.2.0 → 5.0.0
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/package.json +17 -13
- package/src/lib/rating/criteria/scoring/metadata/attributes/spec/evaluateAttributes.spec.ts +81 -0
- package/src/lib/rating/criteria/scoring/metadata/lib/spec/urlHelpers.spec.ts +102 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/animationUrl.spec.ts +43 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/backgroundColor.spec.ts +36 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/description.spec.ts +29 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/externalUrl.spec.ts +44 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/image.spec.ts +55 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/imageData.spec.ts +37 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/name.spec.ts +28 -0
- package/src/lib/rating/criteria/scoring/metadata/spec/youtubeUrl.spec.ts +44 -0
- package/src/lib/rating/spec/evaluateNft.spec.ts +140 -0
- package/src/spec/Diviner.spec.ts +41 -0
- package/src/spec/Plugin.spec.ts +17 -0
- package/src/spec/testData.json +20109 -0
- package/typedoc.json +0 -5
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/* eslint-disable @stylistic/max-len */
|
|
2
|
+
import '@xylabs/vitest-extended'
|
|
3
|
+
|
|
4
|
+
import type { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'
|
|
5
|
+
import {
|
|
6
|
+
describe, expect, it,
|
|
7
|
+
} from 'vitest'
|
|
8
|
+
|
|
9
|
+
import { analyzeNft } from '../analyzeNft.ts'
|
|
10
|
+
|
|
11
|
+
const nfts: NftInfoFields[] = [
|
|
12
|
+
{
|
|
13
|
+
address: '0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85',
|
|
14
|
+
chainId: 1,
|
|
15
|
+
metadata: {
|
|
16
|
+
attributes: [
|
|
17
|
+
{
|
|
18
|
+
display_type: 'date',
|
|
19
|
+
trait_type: 'Created Date',
|
|
20
|
+
value: null,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
display_type: 'number',
|
|
24
|
+
trait_type: 'Length',
|
|
25
|
+
value: 8,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
display_type: 'date',
|
|
29
|
+
trait_type: 'Registration Date',
|
|
30
|
+
value: 1_640_668_437_000,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
display_type: 'date',
|
|
34
|
+
trait_type: 'Expiration Date',
|
|
35
|
+
value: 1_956_237_957_000,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
background_image: 'https://metadata.ens.domains/mainnet/avatar/💩happens.eth',
|
|
39
|
+
description: '💩happens.eth, an ENS name.',
|
|
40
|
+
image_url:
|
|
41
|
+
'https://metadata.ens.domains/mainnet/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/0x727cff87562fe62e86e8147c31e567da501307ce220e074ec61eb51b6afc8e7a/image',
|
|
42
|
+
is_normalized: true,
|
|
43
|
+
name: '💩happens.eth',
|
|
44
|
+
name_length: 8,
|
|
45
|
+
url: 'https://app.ens.domains/name/💩happens.eth',
|
|
46
|
+
version: 0,
|
|
47
|
+
},
|
|
48
|
+
supply: '1',
|
|
49
|
+
tokenId: '51784517368512681240378652206490798036726342785538345603107759690694088494714',
|
|
50
|
+
type: 'ERC721',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
address: '0x8eaaabe11896bd09fb852d3a5248004ec44bc793',
|
|
54
|
+
chainId: 1,
|
|
55
|
+
metadata: {
|
|
56
|
+
animation_url:
|
|
57
|
+
'https://refractions.azureedge.net/refractions/metadata/refractions/0000000000000000000000000000000000000000000000000000000000000007/prism.mp4',
|
|
58
|
+
attributes: [
|
|
59
|
+
{
|
|
60
|
+
display_type: 'date',
|
|
61
|
+
trait_type: 'Publish Date',
|
|
62
|
+
value: 1_643_274_000,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
trait_type: 'Edition',
|
|
66
|
+
value: 'Bridge',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
trait_type: 'Inventory',
|
|
70
|
+
value: 'Artifacts',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
description:
|
|
74
|
+
'🜂🜃🜁🜄 [Prism](https://refractions.xyz/prism) The Lighthouse \r\n Airdropped to all [BAYC](https://opensea.io/collection/boredapeyachtclub) and [CryptoFish](https://cryptofish.io/) members by [Captain Murray #9671](https://opensea.io/muratsayginer). \r\n \r\n **Introducing [refractions.xyz](https://refractions.xyz/)** / _This is a new yet familiar territory. A dimension where metaphors rule physics and fiction builds reality…_ \r\n \r\n [#apefollowape](https://twitter.com/muratsayginer)',
|
|
75
|
+
external_url: 'https://refractions.xyz/',
|
|
76
|
+
image:
|
|
77
|
+
'https://refractions.azureedge.net/refractions/metadata/refractions/0000000000000000000000000000000000000000000000000000000000000007/prism_placeholder.gif',
|
|
78
|
+
name: 'Prism',
|
|
79
|
+
},
|
|
80
|
+
supply: '1',
|
|
81
|
+
tokenId: '7',
|
|
82
|
+
type: 'ERC1155',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
address: '0x0369edc7646948e2f36f9f85baf297bb99843054',
|
|
86
|
+
chainId: 1,
|
|
87
|
+
metadata: {
|
|
88
|
+
attributes: [
|
|
89
|
+
{
|
|
90
|
+
trait_type: 'Artist',
|
|
91
|
+
value: 'MrSnowy10',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
trait_type: 'Item Eaten',
|
|
95
|
+
value: 'Radioactive Waste',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
trait_type: 'Type',
|
|
99
|
+
value: 'Avatar',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
trait_type: 'Species',
|
|
103
|
+
value: 'Pinco',
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
created_by: 'MrSnowy10',
|
|
107
|
+
description: 'Alien Pinco\n\nPinco "Alien"',
|
|
108
|
+
external_url: 'https://www.thepincovillage.com/',
|
|
109
|
+
image: 'https://arweave.net/0-R-VFX6VxkK4Cr70gnq50A2Rd6qXge0sHAQqGPqI4E',
|
|
110
|
+
image_details: {
|
|
111
|
+
bytes: 2_459_769,
|
|
112
|
+
format: 'PNG',
|
|
113
|
+
height: 1500,
|
|
114
|
+
sha256: 'f5cc400e767fe9a5c75c32745faf472ca35863b0ff48662923d7f3c9bae13edd',
|
|
115
|
+
width: 1200,
|
|
116
|
+
},
|
|
117
|
+
image_url: 'https://arweave.net/0-R-VFX6VxkK4Cr70gnq50A2Rd6qXge0sHAQqGPqI4E',
|
|
118
|
+
name: 'Pinco "Alien"',
|
|
119
|
+
},
|
|
120
|
+
supply: '1',
|
|
121
|
+
tokenId: '27',
|
|
122
|
+
type: 'ERC1155',
|
|
123
|
+
},
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
describe('evaluateNft', () => {
|
|
127
|
+
it.each(nfts)('evaluates the NFT', async (nft) => {
|
|
128
|
+
const rating = await analyzeNft(nft)
|
|
129
|
+
expect(rating).toBeObject()
|
|
130
|
+
for (let [key, score] of Object.entries(rating)) {
|
|
131
|
+
expect(key).toBeString()
|
|
132
|
+
const [total, possible] = score
|
|
133
|
+
expect(total).toBeNumber()
|
|
134
|
+
expect(total).not.toBeNegative()
|
|
135
|
+
expect(possible).toBeNumber()
|
|
136
|
+
expect(possible).not.toBeNegative()
|
|
137
|
+
expect(total).toBeLessThanOrEqual(possible)
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import '@xylabs/vitest-extended'
|
|
2
|
+
|
|
3
|
+
import { readFile } from 'node:fs/promises'
|
|
4
|
+
import Path from 'node:path'
|
|
5
|
+
|
|
6
|
+
import type { NftInfo } from '@xyo-network/crypto-nft-payload-plugin'
|
|
7
|
+
import { isNftInfo } from '@xyo-network/crypto-nft-payload-plugin'
|
|
8
|
+
import { PayloadWrapper } from '@xyo-network/payload-wrapper'
|
|
9
|
+
import {
|
|
10
|
+
beforeAll,
|
|
11
|
+
describe, expect, test,
|
|
12
|
+
} from 'vitest'
|
|
13
|
+
|
|
14
|
+
import { isNftScore, NftScoreDiviner } from '../Diviner.ts'
|
|
15
|
+
|
|
16
|
+
describe('NftScoreDiviner', () => {
|
|
17
|
+
let data: NftInfo[]
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
const filePath = Path.join(__dirname, 'testData.json')
|
|
20
|
+
const fileContents = await readFile(filePath, 'utf8')
|
|
21
|
+
const nfts = JSON.parse(fileContents)
|
|
22
|
+
expect(nfts).toBeArray()
|
|
23
|
+
if (Array.isArray(nfts)) {
|
|
24
|
+
data = nfts.filter(isNftInfo)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
test('divine', async () => {
|
|
28
|
+
const diviner = await NftScoreDiviner.create({ account: 'random' })
|
|
29
|
+
const scores = (await diviner.divine(data)).filter(isNftScore)
|
|
30
|
+
expect(scores).toBeArrayOfSize(data.length)
|
|
31
|
+
for (const [i, score] of scores.entries()) {
|
|
32
|
+
const wrapped = PayloadWrapper.wrap(score)
|
|
33
|
+
expect(await wrapped.getValid()).toBe(true)
|
|
34
|
+
const payload = wrapped.payload
|
|
35
|
+
expect(payload?.sources).toBeArrayOfSize(1)
|
|
36
|
+
expect(payload?.sources?.[0]).toBeString()
|
|
37
|
+
const sourceHash = await PayloadWrapper.wrap(data[i]).dataHash()
|
|
38
|
+
expect(payload?.sources?.[0]).toBe(sourceHash)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import '@xylabs/vitest-extended'
|
|
2
|
+
|
|
3
|
+
import { PayloadSetPluginResolver } from '@xyo-network/payloadset-plugin'
|
|
4
|
+
import {
|
|
5
|
+
describe, expect,
|
|
6
|
+
test,
|
|
7
|
+
} from 'vitest'
|
|
8
|
+
|
|
9
|
+
import { NftScoreDivinerPlugin } from '../Plugin.ts'
|
|
10
|
+
|
|
11
|
+
describe('NftScoreDivinerPlugin', () => {
|
|
12
|
+
test('Add to Resolver', async () => {
|
|
13
|
+
const plugin = NftScoreDivinerPlugin()
|
|
14
|
+
const resolver = await new PayloadSetPluginResolver().register(plugin)
|
|
15
|
+
expect(resolver.resolve(plugin.set)).toBeDefined()
|
|
16
|
+
})
|
|
17
|
+
})
|