@xyo-network/evm-token-interface-diviner 4.1.1 → 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.
@@ -1,88 +1,3 @@
1
- import { AbstractDiviner } from '@xyo-network/diviner-abstract';
2
- import { DivinerConfig, DivinerParams } from '@xyo-network/diviner-model';
3
- import { EvmContract } from '@xyo-network/evm-contract-witness';
4
- import { AnyConfigSchema } from '@xyo-network/module-model';
5
- import { Payload, Schema } from '@xyo-network/payload-model';
6
- import { JsonFragment } from 'ethers';
7
-
8
- /**
9
- * ERC20 Token Interfaces
10
- */
11
- type ERC20TokenInterfaces = 'ERC20';
12
- /**
13
- * ERC721 Token Interfaces
14
- */
15
- type ERC721TokenInterfaces = 'ERC721' | 'ERC721TokenReceiver' | 'ERC721Metadata' | 'ERC721Enumerable';
16
- /**
17
- * ERC1155 Token Interfaces
18
- */
19
- type ERC1155TokenInterfaces = 'ERC1155' | 'ERC1155TokenReceiver' | 'ERC1155Metadata_URI';
20
- /**
21
- * All Token Interfaces
22
- */
23
- type TokenInterface = ERC20TokenInterfaces | ERC721TokenInterfaces | ERC1155TokenInterfaces;
24
- /**
25
- * The schema for the EVM Token Interface Implemented payload
26
- */
27
- declare const EvmTokenInterfaceImplementedSchema = "network.xyo.evm.token.interface.implemented";
28
- /**
29
- * The schema for the EVM Token Interface Implemented payload
30
- */
31
- type EvmTokenInterfaceImplementedSchema = typeof EvmTokenInterfaceImplementedSchema;
32
- /**
33
- * The EVM Token Interface Implemented payload
34
- */
35
- type EvmTokenInterfaceImplemented = Payload<{
36
- /**
37
- * The contract address
38
- */
39
- address: string;
40
- /**
41
- * The chain id
42
- */
43
- chainId: number;
44
- /**
45
- * True if the contract implements the interface
46
- */
47
- implemented: boolean;
48
- /**
49
- * The specific token interface
50
- */
51
- tokenInterface: TokenInterface;
52
- }, EvmTokenInterfaceImplementedSchema>;
53
- /**
54
- * Identity function for EvmTokenInterfaceImplemented payload
55
- */
56
- declare const isEvmTokenInterfaceImplemented: (x?: unknown | null) => x is EvmTokenInterfaceImplemented;
57
-
58
- declare const EvmTokenInterfaceImplementedDivinerConfigSchema = "network.xyo.evm.token.interface.implemented.diviner.config";
59
- type EvmTokenInterfaceImplementedDivinerConfigSchema = typeof EvmTokenInterfaceImplementedDivinerConfigSchema;
60
- type EvmTokenInterfaceImplementedDivinerConfig = DivinerConfig<{
61
- schema: EvmTokenInterfaceImplementedDivinerConfigSchema;
62
- tokenInterfaces?: TokenInterface[];
63
- }>;
64
- type EvmTokenInterfaceImplementedDivinerParams = DivinerParams<AnyConfigSchema<EvmTokenInterfaceImplementedDivinerConfig>>;
65
- type DistributiveMappedType<T> = T extends string ? {
66
- [K in T]: readonly JsonFragment[];
67
- } : never;
68
- type TokenInterfaceDictionary = DistributiveMappedType<TokenInterface>;
69
- /**
70
- * A diviner that checks if a contract implements a token interface
71
- */
72
- declare class EvmTokenInterfaceImplementedDiviner<TParams extends EvmTokenInterfaceImplementedDivinerParams = EvmTokenInterfaceImplementedDivinerParams> extends AbstractDiviner<TParams, EvmContract, EvmTokenInterfaceImplemented> {
73
- /**
74
- * The list of supported token interfaces
75
- */
76
- static readonly SupportedTokenInterfaces: Readonly<Record<TokenInterface, readonly JsonFragment[]>>;
77
- static readonly configSchemas: Schema[];
78
- static readonly defaultConfigSchema: Schema;
79
- private _tokenInterfaces?;
80
- /**
81
- * The list of token interfaces to check against the contract
82
- */
83
- get tokenInterfaces(): TokenInterfaceDictionary;
84
- protected divineHandler(inPayloads?: EvmContract[]): Promise<EvmTokenInterfaceImplemented[]>;
85
- }
86
-
87
- export { EvmTokenInterfaceImplementedDiviner, EvmTokenInterfaceImplementedDivinerConfigSchema, EvmTokenInterfaceImplementedSchema, isEvmTokenInterfaceImplemented };
88
- export type { ERC1155TokenInterfaces, ERC20TokenInterfaces, ERC721TokenInterfaces, EvmTokenInterfaceImplemented, EvmTokenInterfaceImplementedDivinerConfig, EvmTokenInterfaceImplementedDivinerParams, TokenInterface };
1
+ export * from './Diviner.ts';
2
+ export * from './Payload.ts';
3
+ //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/evm-token-interface-diviner",
3
- "version": "4.1.1",
3
+ "version": "5.0.0",
4
4
  "description": "Typescript/Javascript Plugins for XYO Platform",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -28,40 +28,43 @@
28
28
  },
29
29
  "module": "dist/neutral/index.mjs",
30
30
  "types": "dist/neutral/index.d.ts",
31
+ "files": [
32
+ "dist",
33
+ "src"
34
+ ],
31
35
  "dependencies": {
32
- "@xylabs/assert": "^4.13.23",
33
- "@xyo-network/diviner-abstract": "^4.1.7",
34
- "@xyo-network/diviner-model": "^4.1.7",
35
- "@xyo-network/evm-contract-witness": "^4.1.1",
36
- "@xyo-network/module-model": "^4.1.7",
36
+ "@xylabs/assert": "^5.0.0",
37
+ "@xyo-network/diviner-abstract": "^5.0.0",
38
+ "@xyo-network/diviner-model": "^5.0.0",
39
+ "@xyo-network/evm-contract-witness": "^5.0.0",
40
+ "@xyo-network/module-model": "^5.0.0",
37
41
  "@xyo-network/open-zeppelin-typechain": "^3.5.4",
38
- "@xyo-network/payload-model": "^4.1.7",
42
+ "@xyo-network/payload-model": "^5.0.0",
39
43
  "ethers": "^6.15.0"
40
44
  },
41
45
  "devDependencies": {
42
- "@xylabs/delay": "^4.13.23",
43
- "@xylabs/ts-scripts-yarn3": "^7.0.0-rc.24",
44
- "@xylabs/tsconfig": "^7.0.0-rc.24",
45
- "@xylabs/vitest-extended": "^4.13.23",
46
- "@xyo-network/archivist-memory": "^4.1.7",
47
- "@xyo-network/boundwitness-model": "^4.1.7",
48
- "@xyo-network/diviner-boundwitness-memory": "^4.1.7",
49
- "@xyo-network/diviner-jsonpatch": "^4.1.7",
50
- "@xyo-network/diviner-payload-generic": "^4.1.7",
51
- "@xyo-network/diviner-payload-memory": "^4.1.7",
52
- "@xyo-network/diviner-payload-model": "^4.1.7",
53
- "@xyo-network/diviner-stateful": "^4.1.7",
54
- "@xyo-network/diviner-temporal-indexing": "^4.1.7",
55
- "@xyo-network/manifest": "^4.1.7",
56
- "@xyo-network/module-factory-locator": "^4.1.7",
57
- "@xyo-network/node-memory": "^4.1.7",
46
+ "@xylabs/delay": "^5.0.0",
47
+ "@xylabs/ts-scripts-yarn3": "^7.0.2",
48
+ "@xylabs/tsconfig": "^7.0.2",
49
+ "@xylabs/vitest-extended": "^5.0.0",
50
+ "@xyo-network/archivist-memory": "^5.0.0",
51
+ "@xyo-network/boundwitness-model": "^5.0.0",
52
+ "@xyo-network/diviner-boundwitness-memory": "^5.0.0",
53
+ "@xyo-network/diviner-jsonpatch": "^5.0.0",
54
+ "@xyo-network/diviner-payload-generic": "^5.0.0",
55
+ "@xyo-network/diviner-payload-memory": "^5.0.0",
56
+ "@xyo-network/diviner-payload-model": "^5.0.0",
57
+ "@xyo-network/diviner-stateful": "^5.0.0",
58
+ "@xyo-network/diviner-temporal-indexing": "^5.0.0",
59
+ "@xyo-network/manifest": "^5.0.0",
60
+ "@xyo-network/module-factory-locator": "^5.0.0",
61
+ "@xyo-network/node-memory": "^5.0.0",
58
62
  "@xyo-network/open-zeppelin-typechain": "^3.5.4",
59
- "@xyo-network/sentinel-model": "^4.1.7",
60
- "@xyo-network/wallet": "^4.1.7",
61
- "@xyo-network/wallet-model": "^4.1.7",
62
- "@xyo-network/witness-evm-abstract": "^4.1.7",
63
- "@xyo-network/witness-timestamp": "^4.1.7",
64
- "knip": "^5.62.0",
63
+ "@xyo-network/sentinel-model": "^5.0.0",
64
+ "@xyo-network/wallet": "^5.0.0",
65
+ "@xyo-network/wallet-model": "^5.0.0",
66
+ "@xyo-network/witness-evm-abstract": "^5.0.0",
67
+ "@xyo-network/witness-timestamp": "^5.0.0",
65
68
  "typescript": "^5.8.3",
66
69
  "vitest": "^3.2.4"
67
70
  },
@@ -0,0 +1,64 @@
1
+ import '@xylabs/vitest-extended'
2
+
3
+ import {
4
+ EvmContractSchema, EvmContractWitness, EvmContractWitnessConfigSchema,
5
+ } from '@xyo-network/evm-contract-witness'
6
+ import { EvmAddressSchema, getProvidersFromEnv } from '@xyo-network/witness-evm-abstract'
7
+ import {
8
+ describe, expect,
9
+ it,
10
+ } from 'vitest'
11
+
12
+ import { EvmTokenInterfaceImplementedDiviner, EvmTokenInterfaceImplementedDivinerConfigSchema } from '../Diviner.ts'
13
+ import type { TokenInterface } from '../Payload.ts'
14
+
15
+ describe.skipIf(!process.env.INFURA_PROJECT_ID)('EvmTokenInterfaceImplementedDiviner', () => {
16
+ type TestData = readonly [string, TokenInterface[]]
17
+ const cases: readonly TestData[] = [
18
+ ['0x55296f69f40ea6d20e478533c15a6b08b654e758', ['ERC20'] as TokenInterface[]], // XYO ERC20
19
+ ['0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', ['ERC721', 'ERC721Metadata', 'ERC721Enumerable', 'ERC721TokenReceiver'] as TokenInterface[]], // BAYC
20
+ ['0x2A6d6a082C410a195157EC4caf67CB9fD718f087', ['ERC1155', 'ERC1155Metadata_URI', 'ERC1155TokenReceiver'] as TokenInterface[]], // Spider Tanks
21
+ ] as const
22
+ describe('divine', () => {
23
+ describe('with matching ABI', () => {
24
+ it.each(cases)('returns implemented true', async (address, tokenInterfaces) => {
25
+ const witness = await EvmContractWitness.create({
26
+ account: 'random',
27
+ config: { schema: EvmContractWitnessConfigSchema },
28
+ providers: getProvidersFromEnv,
29
+ })
30
+ const diviner = await EvmTokenInterfaceImplementedDiviner.create({
31
+ account: 'random',
32
+ config: { schema: EvmTokenInterfaceImplementedDivinerConfigSchema, tokenInterfaces },
33
+ })
34
+ const observations = await witness.observe([{ address, schema: EvmAddressSchema }])
35
+ expect(observations?.length).toBeGreaterThan(0)
36
+ const code = observations?.[0].code
37
+ const results = await diviner.divine([{
38
+ address, block: 0, chainId: 1, code, schema: EvmContractSchema,
39
+ }])
40
+ expect(results?.length).toBeGreaterThan(0)
41
+ for (const result of results ?? []) {
42
+ expect(result.address).toBe(address)
43
+ expect(result.implemented).toBeTrue()
44
+ }
45
+ })
46
+ })
47
+ describe('without matching ABI', () => {
48
+ it.each(cases)('returns implemented false', async (address, tokenInterfaces) => {
49
+ const diviner = await EvmTokenInterfaceImplementedDiviner.create({
50
+ account: 'random',
51
+ config: { schema: EvmTokenInterfaceImplementedDivinerConfigSchema, tokenInterfaces },
52
+ })
53
+ const results = await diviner.divine([{
54
+ address, block: 0, chainId: 1, code: '0x00', schema: EvmContractSchema,
55
+ }])
56
+ expect(results?.length).toBeGreaterThan(0)
57
+ for (const result of results ?? []) {
58
+ expect(result.address).toBe(address)
59
+ expect(result.implemented).toBeFalse()
60
+ }
61
+ })
62
+ })
63
+ })
64
+ })
@@ -0,0 +1,152 @@
1
+ import '@xylabs/vitest-extended'
2
+
3
+ import { assertEx } from '@xylabs/assert'
4
+ import { delay } from '@xylabs/delay'
5
+ import { MemoryArchivist } from '@xyo-network/archivist-memory'
6
+ import type { BoundWitness } from '@xyo-network/boundwitness-model'
7
+ import { isBoundWitness } from '@xyo-network/boundwitness-model'
8
+ import { MemoryBoundWitnessDiviner } from '@xyo-network/diviner-boundwitness-memory'
9
+ import { JsonPatchDiviner } from '@xyo-network/diviner-jsonpatch'
10
+ import { asDivinerInstance } from '@xyo-network/diviner-model'
11
+ import { GenericPayloadDiviner } from '@xyo-network/diviner-payload-generic'
12
+ import { PayloadDivinerQuerySchema } from '@xyo-network/diviner-payload-model'
13
+ import { StatefulDiviner, StatefulDivinerParams } from '@xyo-network/diviner-stateful'
14
+ import {
15
+ TemporalIndexingDiviner,
16
+ TemporalIndexingDivinerDivinerQueryToIndexQueryDiviner,
17
+ TemporalIndexingDivinerIndexCandidateToIndexDiviner,
18
+ TemporalIndexingDivinerIndexQueryResponseToDivinerQueryResponseDiviner,
19
+ TemporalIndexingDivinerStateToIndexCandidateDiviner,
20
+ } from '@xyo-network/diviner-temporal-indexing'
21
+ import type { EvmContract, EvmContractWitnessParams } from '@xyo-network/evm-contract-witness'
22
+ import { EvmContractWitness, isEvmContract } from '@xyo-network/evm-contract-witness'
23
+ import type { ModuleManifest, PackageManifestPayload } from '@xyo-network/manifest'
24
+ import { ManifestWrapper } from '@xyo-network/manifest'
25
+ import { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'
26
+ import {
27
+ creatableModule, CreatableModuleInstance, ModuleFactory, ModuleState,
28
+ } from '@xyo-network/module-model'
29
+ import type { MemoryNode } from '@xyo-network/node-memory'
30
+ import { Payload } from '@xyo-network/payload-model'
31
+ import { asSentinelInstance } from '@xyo-network/sentinel-model'
32
+ import { HDWallet } from '@xyo-network/wallet'
33
+ import type { WalletInstance } from '@xyo-network/wallet-model'
34
+ import type { EvmAddress } from '@xyo-network/witness-evm-abstract'
35
+ import { EvmAddressSchema, getProviderFromEnv } from '@xyo-network/witness-evm-abstract'
36
+ import type { TimeStamp } from '@xyo-network/witness-timestamp'
37
+ import { isTimestamp, TimestampWitness } from '@xyo-network/witness-timestamp'
38
+ import type { Provider } from 'ethers'
39
+ import {
40
+ beforeAll,
41
+ describe, expect, it,
42
+ } from 'vitest'
43
+
44
+ import { EvmTokenInterfaceImplementedDiviner } from '../Diviner.ts'
45
+ import type { TokenInterface } from '../Payload.ts'
46
+ import { isEvmTokenInterfaceImplemented } from '../Payload.ts'
47
+ import contractWitnessManifest from './Contract.Witness.Index.json' with { type: 'json' }
48
+ import tokenDivinerManifest from './Token.Diviner.Index.json' with { type: 'json' }
49
+ import tokenNodeManifest from './TokenNode.json' with { type: 'json' }
50
+
51
+ const maxProviders = 32
52
+
53
+ @creatableModule<CreatableModuleInstance<StatefulDivinerParams>>()
54
+ class TestStatefulDiviner extends StatefulDiviner {
55
+ callCommitState(state: ModuleState) {
56
+ return this.commitState(state)
57
+ }
58
+
59
+ callRetrieveState() {
60
+ return this.retrieveState()
61
+ }
62
+
63
+ protected override divineHandler(payloads?: Payload[]): Promise<Payload[]> {
64
+ return Promise.resolve(payloads ?? [])
65
+ }
66
+ }
67
+
68
+ describe('Contract Node', () => {
69
+ const chainId = 1
70
+ const cases: [TokenInterface, string][] = [
71
+ ['ERC721', '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D'], // BAYC
72
+ ['ERC1155', '0x2A6d6a082C410a195157EC4caf67CB9fD718f087'], // Spider Tanks
73
+ ]
74
+ const getProviders = () => {
75
+ const providers: Provider[] = []
76
+ for (let i = 0; i < maxProviders; i++) {
77
+ providers.push(getProviderFromEnv())
78
+ }
79
+ return providers
80
+ }
81
+ let wallet: WalletInstance
82
+ let node: MemoryNode
83
+ beforeAll(async () => {
84
+ const mnemonic = 'later puppy sound rebuild rebuild noise ozone amazing hope broccoli crystal grief'
85
+ wallet = await HDWallet.fromPhrase(mnemonic)
86
+ const locator = new ModuleFactoryLocator()
87
+ locator.register(MemoryArchivist.factory())
88
+ locator.register(MemoryBoundWitnessDiviner.factory())
89
+ locator.register(GenericPayloadDiviner.factory())
90
+ locator.register(TimestampWitness.factory())
91
+ locator.register(TemporalIndexingDivinerDivinerQueryToIndexQueryDiviner.factory())
92
+ locator.register(TemporalIndexingDivinerIndexCandidateToIndexDiviner.factory())
93
+ locator.register(TemporalIndexingDivinerIndexQueryResponseToDivinerQueryResponseDiviner.factory())
94
+ locator.register(TemporalIndexingDivinerStateToIndexCandidateDiviner.factory())
95
+ locator.register(TemporalIndexingDiviner.factory())
96
+ locator.register(JsonPatchDiviner.factory())
97
+ locator.register(TestStatefulDiviner.factory())
98
+ locator.register(EvmTokenInterfaceImplementedDiviner.factory())
99
+ locator.register(
100
+ new ModuleFactory(EvmContractWitness, { providers: getProviders } as EvmContractWitnessParams),
101
+ )
102
+ const publicChildren: ModuleManifest[] = [...contractWitnessManifest.nodes, ...tokenDivinerManifest.nodes]
103
+ const manifest = new ManifestWrapper(tokenNodeManifest as PackageManifestPayload, wallet, locator, publicChildren)
104
+ node = assertEx((await manifest.loadNodes()).at(0), () => 'Node not loaded')
105
+ const mods = await node.resolve('*')
106
+ expect(mods).toBeDefined()
107
+ })
108
+ describe('Contract Witness Index Node', () => {
109
+ it.each(cases)('With %s (%s)', async (tokenInterface, address) => {
110
+ const contractSentinel = asSentinelInstance(await node.resolve('EvmContractSentinel'))
111
+ expect(contractSentinel).toBeDefined()
112
+ const collectionCallPayload: EvmAddress = {
113
+ address, chainId, schema: EvmAddressSchema,
114
+ }
115
+ const report = await contractSentinel?.report([collectionCallPayload])
116
+ expect(report).toBeDefined()
117
+ expect(report).toBeArrayOfSize(3)
118
+ const [bw, timestamp, contract] = (report as [BoundWitness, TimeStamp, EvmContract]) ?? []
119
+ expect(isBoundWitness(bw)).toBeTrue()
120
+ expect(isTimestamp(timestamp)).toBeTrue()
121
+ expect(isEvmContract(contract)).toBeTrue()
122
+ expect(contract.address).toBe(address)
123
+ expect(contract.chainId).toBe(chainId)
124
+ expect(contract.code).toBeDefined()
125
+ const divinerName = `${tokenInterface}TokenInterfaceImplementedSentinel`
126
+ const tokenSentinel = asSentinelInstance(await node.resolve(divinerName))
127
+ expect(tokenSentinel).toBeDefined()
128
+ const tokenReport = await tokenSentinel?.report([contract])
129
+ expect(tokenReport).toBeDefined()
130
+ const anyInterfacesImplemented = tokenReport?.filter(isEvmTokenInterfaceImplemented).some(i => i.implemented)
131
+ expect(anyInterfacesImplemented).toBeTrue()
132
+ })
133
+ })
134
+ describe.skip('Token Diviner Index Node', () => {
135
+ beforeAll(async () => {
136
+ // Alow indexers to index
137
+ await delay(1000)
138
+ })
139
+ it.each(cases)('With %s (%s)', async (tokenInterface, address) => {
140
+ const divinerModule = await node.resolve('EvmTokenInterfaceImplementedIndexDiviner')
141
+ expect(divinerModule).toBeDefined()
142
+ const diviner = asDivinerInstance(divinerModule)
143
+ expect(diviner).toBeDefined()
144
+ const query = {
145
+ address, chainId, implemented: true, schema: PayloadDivinerQuerySchema, tokenInterface,
146
+ }
147
+ const result = await diviner?.divine([query])
148
+ expect(result).toBeDefined()
149
+ expect(result).toBeArrayOfSize(1)
150
+ })
151
+ })
152
+ })
package/typedoc.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "$schema": "https://typedoc.org/schema.json",
3
- "entryPoints": ["./src/index.ts"],
4
- "tsconfig": "./tsconfig.typedoc.json"
5
- }
package/xy.config.ts DELETED
@@ -1,10 +0,0 @@
1
- import type { XyTsupConfig } from '@xylabs/ts-scripts-yarn3'
2
- const config: XyTsupConfig = {
3
- compile: {
4
- browser: {},
5
- node: {},
6
- neutral: { src: true },
7
- },
8
- }
9
-
10
- export default config