@xyo-network/crypto-nft-collection-witness-plugin 2.79.4 → 2.79.6
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/Plugin.d.cts +1 -21
- package/dist/browser/Plugin.d.cts.map +1 -1
- package/dist/browser/Plugin.d.mts +1 -21
- package/dist/browser/Plugin.d.mts.map +1 -1
- package/dist/browser/Plugin.d.ts +1 -21
- package/dist/browser/Plugin.d.ts.map +1 -1
- package/dist/browser/Witness.d.cts +3 -10
- package/dist/browser/Witness.d.cts.map +1 -1
- package/dist/browser/Witness.d.mts +3 -10
- package/dist/browser/Witness.d.mts.map +1 -1
- package/dist/browser/Witness.d.ts +3 -10
- package/dist/browser/Witness.d.ts.map +1 -1
- package/dist/browser/index.cjs +20 -13
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +22 -15
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/dist/node/Plugin.d.cts +1 -21
- package/dist/node/Plugin.d.cts.map +1 -1
- package/dist/node/Plugin.d.mts +1 -21
- package/dist/node/Plugin.d.mts.map +1 -1
- package/dist/node/Plugin.d.ts +1 -21
- package/dist/node/Plugin.d.ts.map +1 -1
- package/dist/node/Witness.d.cts +3 -10
- package/dist/node/Witness.d.cts.map +1 -1
- package/dist/node/Witness.d.mts +3 -10
- package/dist/node/Witness.d.mts.map +1 -1
- package/dist/node/Witness.d.ts +3 -10
- package/dist/node/Witness.d.ts.map +1 -1
- package/dist/node/index.js +20 -13
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +22 -15
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/package.json +17 -16
- package/src/Witness.ts +7 -24
- package/src/lib/getNftCollectionNfts.ts +24 -6
|
@@ -17,22 +17,6 @@ export declare const CryptoNftCollectionWitnessPlugin: () => import("@xyo-networ
|
|
|
17
17
|
readonly sign?: boolean | undefined;
|
|
18
18
|
readonly storeQueries?: boolean | undefined;
|
|
19
19
|
readonly timestamp?: boolean | undefined;
|
|
20
|
-
} & import("@xyo-network/module-model").ArchivingModuleConfig & Omit<import("@xyo-network/payload-model").SchemaFields & Omit<{
|
|
21
|
-
accountDerivationPath?: string | undefined;
|
|
22
|
-
readonly archivist?: import("@xyo-network/module-model").ArchivistModuleConfig | undefined;
|
|
23
|
-
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
24
|
-
readonly name?: string | undefined;
|
|
25
|
-
readonly paging?: Record<string, {
|
|
26
|
-
size?: number | undefined;
|
|
27
|
-
}> | undefined;
|
|
28
|
-
readonly security?: {
|
|
29
|
-
readonly allowAnonymous?: boolean | undefined;
|
|
30
|
-
readonly allowed?: Record<string, (string | import("@xyo-network/module-model").CosigningAddressSet)[]> | undefined;
|
|
31
|
-
readonly disallowed?: Record<string, string[]> | undefined;
|
|
32
|
-
} | undefined;
|
|
33
|
-
readonly sign?: boolean | undefined;
|
|
34
|
-
readonly storeQueries?: boolean | undefined;
|
|
35
|
-
readonly timestamp?: boolean | undefined;
|
|
36
20
|
} & import("@xyo-network/module-model").ArchivingModuleConfig & {
|
|
37
21
|
archivist?: string | undefined;
|
|
38
22
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
@@ -45,14 +29,10 @@ export declare const CryptoNftCollectionWitnessPlugin: () => import("@xyo-networ
|
|
|
45
29
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
46
30
|
}, "schema"> & {
|
|
47
31
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
48
|
-
}, "schema"> & {
|
|
49
|
-
schema: string;
|
|
50
|
-
}, "schema"> & {
|
|
51
|
-
schema: string;
|
|
52
32
|
};
|
|
53
33
|
ephemeralQueryAccountEnabled?: boolean | undefined;
|
|
54
34
|
wallet?: import("@xyo-network/wallet-model").WalletInstance | undefined;
|
|
55
35
|
} & {
|
|
56
|
-
|
|
36
|
+
providers: () => import("@xylabs/promise").Promisable<import("@ethersproject/providers").BaseProvider[]>;
|
|
57
37
|
}>>;
|
|
58
38
|
//# sourceMappingURL=Plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAEtD,eAAO,MAAM,gCAAgC
|
|
1
|
+
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAEtD,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAS1C,CAAA"}
|
|
@@ -17,22 +17,6 @@ export declare const CryptoNftCollectionWitnessPlugin: () => import("@xyo-networ
|
|
|
17
17
|
readonly sign?: boolean | undefined;
|
|
18
18
|
readonly storeQueries?: boolean | undefined;
|
|
19
19
|
readonly timestamp?: boolean | undefined;
|
|
20
|
-
} & import("@xyo-network/module-model").ArchivingModuleConfig & Omit<import("@xyo-network/payload-model").SchemaFields & Omit<{
|
|
21
|
-
accountDerivationPath?: string | undefined;
|
|
22
|
-
readonly archivist?: import("@xyo-network/module-model").ArchivistModuleConfig | undefined;
|
|
23
|
-
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
24
|
-
readonly name?: string | undefined;
|
|
25
|
-
readonly paging?: Record<string, {
|
|
26
|
-
size?: number | undefined;
|
|
27
|
-
}> | undefined;
|
|
28
|
-
readonly security?: {
|
|
29
|
-
readonly allowAnonymous?: boolean | undefined;
|
|
30
|
-
readonly allowed?: Record<string, (string | import("@xyo-network/module-model").CosigningAddressSet)[]> | undefined;
|
|
31
|
-
readonly disallowed?: Record<string, string[]> | undefined;
|
|
32
|
-
} | undefined;
|
|
33
|
-
readonly sign?: boolean | undefined;
|
|
34
|
-
readonly storeQueries?: boolean | undefined;
|
|
35
|
-
readonly timestamp?: boolean | undefined;
|
|
36
20
|
} & import("@xyo-network/module-model").ArchivingModuleConfig & {
|
|
37
21
|
archivist?: string | undefined;
|
|
38
22
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
@@ -45,14 +29,10 @@ export declare const CryptoNftCollectionWitnessPlugin: () => import("@xyo-networ
|
|
|
45
29
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
46
30
|
}, "schema"> & {
|
|
47
31
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
48
|
-
}, "schema"> & {
|
|
49
|
-
schema: string;
|
|
50
|
-
}, "schema"> & {
|
|
51
|
-
schema: string;
|
|
52
32
|
};
|
|
53
33
|
ephemeralQueryAccountEnabled?: boolean | undefined;
|
|
54
34
|
wallet?: import("@xyo-network/wallet-model").WalletInstance | undefined;
|
|
55
35
|
} & {
|
|
56
|
-
|
|
36
|
+
providers: () => import("@xylabs/promise").Promisable<import("@ethersproject/providers").BaseProvider[]>;
|
|
57
37
|
}>>;
|
|
58
38
|
//# sourceMappingURL=Plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAEtD,eAAO,MAAM,gCAAgC
|
|
1
|
+
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAEtD,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAS1C,CAAA"}
|
package/dist/browser/Plugin.d.ts
CHANGED
|
@@ -17,22 +17,6 @@ export declare const CryptoNftCollectionWitnessPlugin: () => import("@xyo-networ
|
|
|
17
17
|
readonly sign?: boolean | undefined;
|
|
18
18
|
readonly storeQueries?: boolean | undefined;
|
|
19
19
|
readonly timestamp?: boolean | undefined;
|
|
20
|
-
} & import("@xyo-network/module-model").ArchivingModuleConfig & Omit<import("@xyo-network/payload-model").SchemaFields & Omit<{
|
|
21
|
-
accountDerivationPath?: string | undefined;
|
|
22
|
-
readonly archivist?: import("@xyo-network/module-model").ArchivistModuleConfig | undefined;
|
|
23
|
-
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
24
|
-
readonly name?: string | undefined;
|
|
25
|
-
readonly paging?: Record<string, {
|
|
26
|
-
size?: number | undefined;
|
|
27
|
-
}> | undefined;
|
|
28
|
-
readonly security?: {
|
|
29
|
-
readonly allowAnonymous?: boolean | undefined;
|
|
30
|
-
readonly allowed?: Record<string, (string | import("@xyo-network/module-model").CosigningAddressSet)[]> | undefined;
|
|
31
|
-
readonly disallowed?: Record<string, string[]> | undefined;
|
|
32
|
-
} | undefined;
|
|
33
|
-
readonly sign?: boolean | undefined;
|
|
34
|
-
readonly storeQueries?: boolean | undefined;
|
|
35
|
-
readonly timestamp?: boolean | undefined;
|
|
36
20
|
} & import("@xyo-network/module-model").ArchivingModuleConfig & {
|
|
37
21
|
archivist?: string | undefined;
|
|
38
22
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
@@ -45,14 +29,10 @@ export declare const CryptoNftCollectionWitnessPlugin: () => import("@xyo-networ
|
|
|
45
29
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
46
30
|
}, "schema"> & {
|
|
47
31
|
schema: "network.xyo.crypto.nft.collection.witness.config";
|
|
48
|
-
}, "schema"> & {
|
|
49
|
-
schema: string;
|
|
50
|
-
}, "schema"> & {
|
|
51
|
-
schema: string;
|
|
52
32
|
};
|
|
53
33
|
ephemeralQueryAccountEnabled?: boolean | undefined;
|
|
54
34
|
wallet?: import("@xyo-network/wallet-model").WalletInstance | undefined;
|
|
55
35
|
} & {
|
|
56
|
-
|
|
36
|
+
providers: () => import("@xylabs/promise").Promisable<import("@ethersproject/providers").BaseProvider[]>;
|
|
57
37
|
}>>;
|
|
58
38
|
//# sourceMappingURL=Plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAEtD,eAAO,MAAM,gCAAgC
|
|
1
|
+
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAA;AAEtD,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAS1C,CAAA"}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { InfuraProvider, Provider, WebSocketProvider } from '@ethersproject/providers';
|
|
2
|
-
import { AbstractWitness } from '@xyo-network/abstract-witness';
|
|
3
1
|
import { NftCollectionInfo, NftCollectionWitnessConfig, NftCollectionWitnessQuery } from '@xyo-network/crypto-nft-collection-payload-plugin';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
provider: Provider;
|
|
8
|
-
}>;
|
|
9
|
-
export declare class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {
|
|
2
|
+
import { AbstractBlockchainWitness, BlockchainWitnessParams } from '@xyo-network/witness-blockchain-abstract';
|
|
3
|
+
export type CryptoNftCollectionWitnessParams = BlockchainWitnessParams<NftCollectionWitnessConfig>;
|
|
4
|
+
export declare class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractBlockchainWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {
|
|
10
5
|
static configSchemas: "network.xyo.crypto.nft.collection.witness.config"[];
|
|
11
|
-
protected providers: Record<number, WebSocketProvider | InfuraProvider>;
|
|
12
|
-
protected getProvider(chainId: number): WebSocketProvider | InfuraProvider;
|
|
13
6
|
protected observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]>;
|
|
14
7
|
}
|
|
15
8
|
//# sourceMappingURL=Witness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,iBAAiB,EAEjB,0BAA0B,EAE1B,yBAAyB,EAC1B,MAAM,mDAAmD,CAAA;AAE1D,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAI7G,MAAM,MAAM,gCAAgC,GAAG,uBAAuB,CAAC,0BAA0B,CAAC,CAAA;AAoBlG,qBAAa,0BAA0B,CACrC,OAAO,SAAS,gCAAgC,GAAG,gCAAgC,CACnF,SAAQ,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,CAAC;IACxF,OAAgB,aAAa,uDAAqC;cAEzC,cAAc,CAAC,QAAQ,CAAC,EAAE,yBAAyB,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAkD9G"}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { InfuraProvider, Provider, WebSocketProvider } from '@ethersproject/providers';
|
|
2
|
-
import { AbstractWitness } from '@xyo-network/abstract-witness';
|
|
3
1
|
import { NftCollectionInfo, NftCollectionWitnessConfig, NftCollectionWitnessQuery } from '@xyo-network/crypto-nft-collection-payload-plugin';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
provider: Provider;
|
|
8
|
-
}>;
|
|
9
|
-
export declare class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {
|
|
2
|
+
import { AbstractBlockchainWitness, BlockchainWitnessParams } from '@xyo-network/witness-blockchain-abstract';
|
|
3
|
+
export type CryptoNftCollectionWitnessParams = BlockchainWitnessParams<NftCollectionWitnessConfig>;
|
|
4
|
+
export declare class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractBlockchainWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {
|
|
10
5
|
static configSchemas: "network.xyo.crypto.nft.collection.witness.config"[];
|
|
11
|
-
protected providers: Record<number, WebSocketProvider | InfuraProvider>;
|
|
12
|
-
protected getProvider(chainId: number): WebSocketProvider | InfuraProvider;
|
|
13
6
|
protected observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]>;
|
|
14
7
|
}
|
|
15
8
|
//# sourceMappingURL=Witness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,iBAAiB,EAEjB,0BAA0B,EAE1B,yBAAyB,EAC1B,MAAM,mDAAmD,CAAA;AAE1D,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAI7G,MAAM,MAAM,gCAAgC,GAAG,uBAAuB,CAAC,0BAA0B,CAAC,CAAA;AAoBlG,qBAAa,0BAA0B,CACrC,OAAO,SAAS,gCAAgC,GAAG,gCAAgC,CACnF,SAAQ,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,CAAC;IACxF,OAAgB,aAAa,uDAAqC;cAEzC,cAAc,CAAC,QAAQ,CAAC,EAAE,yBAAyB,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAkD9G"}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { InfuraProvider, Provider, WebSocketProvider } from '@ethersproject/providers';
|
|
2
|
-
import { AbstractWitness } from '@xyo-network/abstract-witness';
|
|
3
1
|
import { NftCollectionInfo, NftCollectionWitnessConfig, NftCollectionWitnessQuery } from '@xyo-network/crypto-nft-collection-payload-plugin';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
provider: Provider;
|
|
8
|
-
}>;
|
|
9
|
-
export declare class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {
|
|
2
|
+
import { AbstractBlockchainWitness, BlockchainWitnessParams } from '@xyo-network/witness-blockchain-abstract';
|
|
3
|
+
export type CryptoNftCollectionWitnessParams = BlockchainWitnessParams<NftCollectionWitnessConfig>;
|
|
4
|
+
export declare class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractBlockchainWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {
|
|
10
5
|
static configSchemas: "network.xyo.crypto.nft.collection.witness.config"[];
|
|
11
|
-
protected providers: Record<number, WebSocketProvider | InfuraProvider>;
|
|
12
|
-
protected getProvider(chainId: number): WebSocketProvider | InfuraProvider;
|
|
13
6
|
protected observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]>;
|
|
14
7
|
}
|
|
15
8
|
//# sourceMappingURL=Witness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,iBAAiB,EAEjB,0BAA0B,EAE1B,yBAAyB,EAC1B,MAAM,mDAAmD,CAAA;AAE1D,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAI7G,MAAM,MAAM,gCAAgC,GAAG,uBAAuB,CAAC,0BAA0B,CAAC,CAAA;AAoBlG,qBAAa,0BAA0B,CACrC,OAAO,SAAS,gCAAgC,GAAG,gCAAgC,CACnF,SAAQ,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,CAAC;IACxF,OAAgB,aAAa,uDAAqC;cAEzC,cAAc,CAAC,QAAQ,CAAC,EAAE,yBAAyB,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAkD9G"}
|
package/dist/browser/index.cjs
CHANGED
|
@@ -40,7 +40,6 @@ var import_payloadset_plugin = require("@xyo-network/payloadset-plugin");
|
|
|
40
40
|
// src/Witness.ts
|
|
41
41
|
var import_assert = require("@xylabs/assert");
|
|
42
42
|
var import_eth_address = require("@xylabs/eth-address");
|
|
43
|
-
var import_abstract_witness = require("@xyo-network/abstract-witness");
|
|
44
43
|
var import_core = require("@xyo-network/core");
|
|
45
44
|
var import_crypto_nft_collection_payload_plugin = require("@xyo-network/crypto-nft-collection-payload-plugin");
|
|
46
45
|
var import_open_zeppelin_typechain3 = require("@xyo-network/open-zeppelin-typechain");
|
|
@@ -123,8 +122,11 @@ var contractHasFunctions = async (provider, address, contractInterface, function
|
|
|
123
122
|
};
|
|
124
123
|
|
|
125
124
|
// src/lib/getNftCollectionNfts.ts
|
|
125
|
+
var import_axios = require("@xylabs/axios");
|
|
126
|
+
var import_bignumber = require("@xylabs/bignumber");
|
|
126
127
|
var import_exists = require("@xylabs/exists");
|
|
127
|
-
var
|
|
128
|
+
var import_blockchain_erc1822_witness = require("@xyo-network/blockchain-erc1822-witness");
|
|
129
|
+
var import_blockchain_erc1967_witness = require("@xyo-network/blockchain-erc1967-witness");
|
|
128
130
|
var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
|
|
129
131
|
var import_open_zeppelin_typechain2 = require("@xyo-network/open-zeppelin-typechain");
|
|
130
132
|
var import_witness_blockchain_abstract = require("@xyo-network/witness-blockchain-abstract");
|
|
@@ -164,12 +166,21 @@ var tryCall = async (func, name) => {
|
|
|
164
166
|
|
|
165
167
|
// src/lib/getNftCollectionNfts.ts
|
|
166
168
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
169
|
+
var hexBytesOnlyOnly = (value) => {
|
|
170
|
+
return value.startsWith("0x") ? value.substring(2) : value;
|
|
171
|
+
};
|
|
172
|
+
var isHexZero = (value) => {
|
|
173
|
+
return value === void 0 ? true : new import_bignumber.BigNumber(hexBytesOnlyOnly(value), "hex").eqn(0);
|
|
174
|
+
};
|
|
167
175
|
function range(size, startAt = 0) {
|
|
168
176
|
return [...Array(size).keys()].map((i) => i + startAt);
|
|
169
177
|
}
|
|
170
178
|
var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
|
|
171
179
|
try {
|
|
172
|
-
const
|
|
180
|
+
const block = await provider.getBlockNumber();
|
|
181
|
+
const erc1967Status = await (0, import_blockchain_erc1967_witness.getErc1967Status)(provider, contractAddress, block);
|
|
182
|
+
const erc1822Status = await (0, import_blockchain_erc1822_witness.getErc1822Status)(provider, contractAddress, block);
|
|
183
|
+
const implementation = isHexZero(erc1967Status.slots.implementation) ? erc1822Status.implementation : erc1967Status.implementation;
|
|
173
184
|
const axios = new import_axios.AxiosJson({ timeout: 2e3 });
|
|
174
185
|
const enumerable = import_open_zeppelin_typechain2.ERC721Enumerable__factory.connect(implementation, provider);
|
|
175
186
|
const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(implementation, provider);
|
|
@@ -178,10 +189,10 @@ var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 10
|
|
|
178
189
|
const maxNftsArray = range(maxNfts);
|
|
179
190
|
const result = (await Promise.all(
|
|
180
191
|
maxNftsArray.map(async (_value, i) => {
|
|
181
|
-
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString()) ?? `${i}`;
|
|
192
|
+
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i, { blockTag: block })).toHexString()) ?? `${i}`;
|
|
182
193
|
if (tokenId !== void 0) {
|
|
183
|
-
const supply = finalTypes.includes((0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155")) ? await tryCall(async () => (await supply1155.totalSupply(tokenId)).toHexString()) ?? "0x01" : "0x01";
|
|
184
|
-
const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId));
|
|
194
|
+
const supply = finalTypes.includes((0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155")) ? await tryCall(async () => (await supply1155.totalSupply(tokenId, { blockTag: block })).toHexString()) ?? "0x01" : "0x01";
|
|
195
|
+
const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, { blockTag: block }));
|
|
185
196
|
const checkedMetaDataUri = metadataUri ? (0, import_witness_blockchain_abstract.checkIpfsUrl)(metadataUri, ipfsGateway) : void 0;
|
|
186
197
|
let metadata = void 0;
|
|
187
198
|
if (checkedMetaDataUri !== void 0) {
|
|
@@ -228,20 +239,16 @@ function resolvedValue(settled, assert) {
|
|
|
228
239
|
}
|
|
229
240
|
return settled.status === "fulfilled" ? settled.value : void 0;
|
|
230
241
|
}
|
|
231
|
-
var CryptoNftCollectionWitness = class extends
|
|
242
|
+
var CryptoNftCollectionWitness = class extends import_witness_blockchain_abstract2.AbstractBlockchainWitness {
|
|
232
243
|
static configSchemas = [import_crypto_nft_collection_payload_plugin.NftCollectionWitnessConfigSchema];
|
|
233
|
-
providers = {};
|
|
234
|
-
getProvider(chainId) {
|
|
235
|
-
this.providers[chainId] = this.providers[chainId] ?? (0, import_witness_blockchain_abstract2.getProviderFromEnv)(chainId);
|
|
236
|
-
return this.providers[chainId];
|
|
237
|
-
}
|
|
238
244
|
async observeHandler(payloads) {
|
|
239
245
|
await this.started("throw");
|
|
246
|
+
await this.getProviders();
|
|
240
247
|
const queries = payloads?.filter(import_crypto_nft_collection_payload_plugin.isNftCollectionWitnessQuery) ?? [];
|
|
241
248
|
const observations = await Promise.all(
|
|
242
249
|
queries.map(async (query) => {
|
|
243
250
|
const chainId = (0, import_assert.assertEx)(query?.chainId || this.config.chainId, "params.chainId is required");
|
|
244
|
-
const provider = this.getProvider(
|
|
251
|
+
const provider = await this.getProvider(true, true);
|
|
245
252
|
const address = (0, import_assert.assertEx)(
|
|
246
253
|
import_eth_address.EthAddress.parse((0, import_assert.assertEx)(query?.address || this.config.address, "params.address is required")),
|
|
247
254
|
"Failed to parse params.address"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts","../../src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts","../../src/lib/collectionMetrics/getNftCollectionMetrics.ts","../../src/lib/contractHasFunctions.ts","../../src/lib/getNftCollectionNfts.ts","../../src/lib/tokenTypes.ts","../../src/lib/tryCall.ts"],"sourcesContent":["import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness'\n\nexport const CryptoNftCollectionWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoNftCollectionWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoNftCollectionWitness.create(params)\n return result\n },\n },\n )\n","import { InfuraProvider, Provider, WebSocketProvider } from '@ethersproject/providers'\nimport { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport { PayloadHasher } from '@xyo-network/core'\nimport {\n isNftCollectionWitnessQuery,\n NftCollectionInfo,\n NftCollectionSchema,\n NftCollectionWitnessConfig,\n NftCollectionWitnessConfigSchema,\n NftCollectionWitnessQuery,\n} from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { ERC721Enumerable__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { getProviderFromEnv } from '@xyo-network/witness-blockchain-abstract'\nimport { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftCollectionMetrics, getNftCollectionNfts, tokenTypes } from './lib'\n\nexport type CryptoNftCollectionWitnessParams = WitnessParams<\n AnyConfigSchema<NftCollectionWitnessConfig>,\n {\n provider: Provider\n }\n>\n\nconst defaultMaxNfts = 100\n\n/**\n * A \"no operation\" Promise to be used\n * when no action is desired but a Promise\n * is required to be returned\n */\nconst NoOp = Promise.resolve()\n\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert: true): T\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: false): T | undefined\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: boolean) {\n if (assert && settled.status === 'rejected') {\n throw settled.reason\n }\n return settled.status === 'fulfilled' ? settled.value : undefined\n}\n\nexport class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractWitness<\n TParams,\n NftCollectionWitnessQuery,\n NftCollectionInfo\n> {\n static override configSchemas = [NftCollectionWitnessConfigSchema]\n\n protected providers: Record<number, WebSocketProvider | InfuraProvider> = {}\n\n protected getProvider(chainId: number) {\n this.providers[chainId] = this.providers[chainId] ?? getProviderFromEnv(chainId)\n return this.providers[chainId]\n }\n\n protected override async observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map<Promise<NftCollectionInfo>>(async (query) => {\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const provider = this.getProvider(chainId)\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n\n const erc721Enumerable = ERC721Enumerable__factory.connect(address, provider)\n\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([\n await erc721Enumerable.name(),\n await erc721Enumerable.symbol(),\n (await erc721Enumerable.totalSupply()).toNumber(),\n await tokenTypes(provider, address),\n await this.writeArchivist(),\n ])\n const types = resolvedValue(typesSettled, true)\n const nfts = await getNftCollectionNfts(address, provider, types, maxNfts)\n const metrics = getNftCollectionMetrics(nfts)\n const archivist = resolvedValue(archivistSettled)\n const [sources] = await Promise.all([\n // Hash all the payloads\n Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),\n // Insert them into the archivist if we have one\n archivist ? archivist.insert(nfts) : NoOp,\n ])\n const payload: NftCollectionInfo = {\n address,\n chainId,\n metrics,\n name: resolvedValue(name, true),\n schema: NftCollectionSchema,\n sources,\n symbol: resolvedValue(symbol, true),\n total: resolvedValue(total, true),\n type: types.at(0),\n types,\n }\n return payload\n }),\n )\n return observations.flat()\n }\n}\n","import { Distribution } from './distribution'\n\nexport const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {\n const distribution: Distribution<T> = {}\n\n array.forEach((item) => {\n for (const property in item) {\n if (Object.prototype.hasOwnProperty.call(item, property)) {\n const value = item[property as keyof T]\n if (value !== undefined && value !== null) {\n const valueString = value.toString()\n if (!distribution[property]) {\n distribution[property] = { [valueString]: 1 }\n } else if (!distribution[property]![valueString]) {\n ;(distribution[property] as Record<string, number>)[valueString] = 1\n } else {\n ;(distribution[property] as Record<string, number>)[valueString] += 1\n }\n }\n }\n }\n })\n\n return distribution\n}\n","import { BinomialDistributionParameters } from '@xyo-network/crypto-nft-collection-payload-plugin'\n\n/**\n * Calculates the parameters of a binomial distribution given the number of trials and success probability\n * @param n Number of trials\n * @param p Success probability\n * @returns The binomial distribution parameters\n */\nexport const calculateBinomialParamsFromProbability = (n: number, p: number): BinomialDistributionParameters => {\n // Mean (µ)\n const mean = n * p\n\n // Variance (σ^2)\n const variance = n * p * (1 - p)\n\n // Standard Deviation (σ)\n const stdDev = Math.sqrt(variance)\n\n return { mean, p, stdDev, variance }\n}\n","import { NftCollectionMetrics, NftTraitMetrics } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { NftInfoFields, OpenSeaNftAttribute } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { calculateAllPropertiesDistribution, calculateBinomialParamsFromProbability } from './lib'\n\ntype TraitDistributionEntry = [string, { [key: string]: number }]\n\nexport const getNftCollectionMetrics = (nfts: NftInfoFields[]): NftCollectionMetrics => {\n const traits = nfts\n .map((nft) => nft?.metadata?.attributes as OpenSeaNftAttribute[] | undefined)\n .filter((v): v is OpenSeaNftAttribute[] => v !== undefined)\n .map((attributes) => {\n return Object.fromEntries(attributes.map((attribute) => [attribute.trait_type, attribute.value]))\n })\n const distribution = calculateAllPropertiesDistribution(traits)\n const n = nfts.length\n const attributes = Object.fromEntries(\n Object.entries(distribution)\n .filter((v): v is TraitDistributionEntry => v[1] !== undefined)\n .map(([trait, entries]) => {\n const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0)\n const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n)\n const values = Object.fromEntries(\n Object.entries(entries).map(([value, traitValueCount]) => {\n const { p } = calculateBinomialParamsFromProbability(n, traitValueCount / n)\n const metrics: NftTraitMetrics = { binomial: { p }, count: traitValueCount }\n return [value, metrics]\n }),\n )\n return [trait, { metrics: { binomial: { p }, count: traitCount }, values }]\n }),\n )\n return { metadata: { attributes } }\n}\n","import { Interface } from '@ethersproject/abi'\nimport { Provider } from '@ethersproject/providers'\n\nexport const contractHasFunctions = async (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => {\n try {\n const bytecode = await provider.getCode(address, 'latest')\n for (let i = 0; i < functionNames.length; i++) {\n const nameSig = contractInterface.getSighash(functionNames[i]).substring(2)\n if (!bytecode.includes(nameSig)) {\n return false\n }\n return true\n }\n return false\n } catch (ex) {\n const error = ex as Error\n console.log(error)\n return false\n }\n}\n","import { BaseProvider } from '@ethersproject/providers'\nimport { exists } from '@xylabs/exists'\nimport { AxiosJson } from '@xyo-network/axios'\nimport { NftInfo, NftMetadata, NftSchema, TokenType, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { checkIpfsUrl, getErc1967Status } from '@xyo-network/witness-blockchain-abstract'\n\nimport { tokenTypes } from './tokenTypes'\nimport { tryCall } from './tryCall'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\nfunction range(size: number, startAt: number = 0): ReadonlyArray<number> {\n return [...Array(size).keys()].map((i) => i + startAt)\n}\n\nexport const getNftCollectionNfts = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: BaseProvider,\n types?: TokenType[],\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n maxNfts = 100,\n): Promise<NftInfo[]> => {\n try {\n //Check if ERC-1967 Upgradeable\n const { implementation } = await getErc1967Status(provider, contractAddress)\n\n const axios = new AxiosJson({ timeout: 2000 })\n const enumerable = ERC721Enumerable__factory.connect(implementation, provider)\n const storage = ERC721URIStorage__factory.connect(implementation, provider)\n const supply1155 = ERC1155Supply__factory.connect(implementation, provider)\n const finalTypes = types ?? (await tokenTypes(provider, implementation))\n\n const maxNftsArray = range(maxNfts)\n\n const result: NftInfo[] = (\n await Promise.all(\n maxNftsArray.map(async (_value, i) => {\n const tokenId = (await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString())) ?? `${i}`\n if (tokenId !== undefined) {\n const supply = finalTypes.includes(toTokenType('ERC1155'))\n ? (await tryCall(async () => (await supply1155.totalSupply(tokenId)).toHexString())) ?? '0x01'\n : '0x01'\n const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId))\n const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : undefined\n let metadata: NftMetadata | undefined = undefined\n if (checkedMetaDataUri !== undefined) {\n try {\n metadata = (await axios.get(checkedMetaDataUri)).data\n } catch (ex) {\n const error = ex as Error\n console.error(`Get Metadata failed: ${error.message}`)\n }\n }\n\n const info: NftInfo = {\n address: contractAddress,\n chainId: provider.network.chainId,\n metadata,\n metadataUri,\n schema: NftSchema,\n supply,\n tokenId,\n type: finalTypes.at(0),\n types: finalTypes,\n }\n if (implementation !== contractAddress) {\n info.implementation = implementation\n }\n return info\n }\n }),\n )\n ).filter(exists)\n return result\n } catch (ex) {\n const error = ex as Error\n console.error(`getNftCollectionNfts failed: [${error.name}] ${error.message}`)\n console.log(error.stack)\n return []\n }\n}\n","import { Provider } from '@ethersproject/providers'\nimport { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC1155URIStorage__factory, IERC721Metadata__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { contractHasFunctions } from './contractHasFunctions'\n\nexport const isErc1155 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, ERC1155URIStorage__factory.createInterface(), ['uri'])\n}\n\nexport const isErc721 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, IERC721Metadata__factory.createInterface(), ['name', 'symbol', 'tokenURI'])\n}\n\nexport const tokenTypes = async (provider: Provider, address: string) => {\n const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)])\n const result: TokenType[] = []\n if (erc721) {\n result.push('ERC721')\n }\n if (erc1155) {\n result.push('ERC1155')\n }\n return result\n}\n","export const tryCall = async <T>(func: () => Promise<T>, name?: string): Promise<T | undefined> => {\n try {\n return await func()\n } catch (ex) {\n if (name) {\n const error = ex as Error\n console.log(`tryCall failed [${name}]: ${error.message}`)\n }\n return undefined\n }\n}\n"],"mappings":"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","names":["import_crypto_nft_payload_plugin","import_open_zeppelin_typechain","import_witness_blockchain_abstract","attributes","p","import_open_zeppelin_typechain"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts","../../src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts","../../src/lib/collectionMetrics/getNftCollectionMetrics.ts","../../src/lib/contractHasFunctions.ts","../../src/lib/getNftCollectionNfts.ts","../../src/lib/tokenTypes.ts","../../src/lib/tryCall.ts"],"sourcesContent":["import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness'\n\nexport const CryptoNftCollectionWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoNftCollectionWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoNftCollectionWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { PayloadHasher } from '@xyo-network/core'\nimport {\n isNftCollectionWitnessQuery,\n NftCollectionInfo,\n NftCollectionSchema,\n NftCollectionWitnessConfig,\n NftCollectionWitnessConfigSchema,\n NftCollectionWitnessQuery,\n} from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { ERC721Enumerable__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { AbstractBlockchainWitness, BlockchainWitnessParams } from '@xyo-network/witness-blockchain-abstract'\n\nimport { getNftCollectionMetrics, getNftCollectionNfts, tokenTypes } from './lib'\n\nexport type CryptoNftCollectionWitnessParams = BlockchainWitnessParams<NftCollectionWitnessConfig>\n\nconst defaultMaxNfts = 100\n\n/**\n * A \"no operation\" Promise to be used\n * when no action is desired but a Promise\n * is required to be returned\n */\nconst NoOp = Promise.resolve()\n\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert: true): T\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: false): T | undefined\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: boolean) {\n if (assert && settled.status === 'rejected') {\n throw settled.reason\n }\n return settled.status === 'fulfilled' ? settled.value : undefined\n}\n\nexport class CryptoNftCollectionWitness<\n TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams,\n> extends AbstractBlockchainWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {\n static override configSchemas = [NftCollectionWitnessConfigSchema]\n\n protected override async observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]> {\n await this.started('throw')\n await this.getProviders() //make sure cache clears\n const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map<Promise<NftCollectionInfo>>(async (query) => {\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const provider = await this.getProvider(true, true)\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n\n const erc721Enumerable = ERC721Enumerable__factory.connect(address, provider)\n\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([\n await erc721Enumerable.name(),\n await erc721Enumerable.symbol(),\n (await erc721Enumerable.totalSupply()).toNumber(),\n await tokenTypes(provider, address),\n await this.writeArchivist(),\n ])\n const types = resolvedValue(typesSettled, true)\n const nfts = await getNftCollectionNfts(address, provider, types, maxNfts)\n const metrics = getNftCollectionMetrics(nfts)\n const archivist = resolvedValue(archivistSettled)\n const [sources] = await Promise.all([\n // Hash all the payloads\n Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),\n // Insert them into the archivist if we have one\n archivist ? archivist.insert(nfts) : NoOp,\n ])\n const payload: NftCollectionInfo = {\n address,\n chainId,\n metrics,\n name: resolvedValue(name, true),\n schema: NftCollectionSchema,\n sources,\n symbol: resolvedValue(symbol, true),\n total: resolvedValue(total, true),\n type: types.at(0),\n types,\n }\n return payload\n }),\n )\n return observations.flat()\n }\n}\n","import { Distribution } from './distribution'\n\nexport const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {\n const distribution: Distribution<T> = {}\n\n array.forEach((item) => {\n for (const property in item) {\n if (Object.prototype.hasOwnProperty.call(item, property)) {\n const value = item[property as keyof T]\n if (value !== undefined && value !== null) {\n const valueString = value.toString()\n if (!distribution[property]) {\n distribution[property] = { [valueString]: 1 }\n } else if (!distribution[property]![valueString]) {\n ;(distribution[property] as Record<string, number>)[valueString] = 1\n } else {\n ;(distribution[property] as Record<string, number>)[valueString] += 1\n }\n }\n }\n }\n })\n\n return distribution\n}\n","import { BinomialDistributionParameters } from '@xyo-network/crypto-nft-collection-payload-plugin'\n\n/**\n * Calculates the parameters of a binomial distribution given the number of trials and success probability\n * @param n Number of trials\n * @param p Success probability\n * @returns The binomial distribution parameters\n */\nexport const calculateBinomialParamsFromProbability = (n: number, p: number): BinomialDistributionParameters => {\n // Mean (µ)\n const mean = n * p\n\n // Variance (σ^2)\n const variance = n * p * (1 - p)\n\n // Standard Deviation (σ)\n const stdDev = Math.sqrt(variance)\n\n return { mean, p, stdDev, variance }\n}\n","import { NftCollectionMetrics, NftTraitMetrics } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { NftInfoFields, OpenSeaNftAttribute } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { calculateAllPropertiesDistribution, calculateBinomialParamsFromProbability } from './lib'\n\ntype TraitDistributionEntry = [string, { [key: string]: number }]\n\nexport const getNftCollectionMetrics = (nfts: NftInfoFields[]): NftCollectionMetrics => {\n const traits = nfts\n .map((nft) => nft?.metadata?.attributes as OpenSeaNftAttribute[] | undefined)\n .filter((v): v is OpenSeaNftAttribute[] => v !== undefined)\n .map((attributes) => {\n return Object.fromEntries(attributes.map((attribute) => [attribute.trait_type, attribute.value]))\n })\n const distribution = calculateAllPropertiesDistribution(traits)\n const n = nfts.length\n const attributes = Object.fromEntries(\n Object.entries(distribution)\n .filter((v): v is TraitDistributionEntry => v[1] !== undefined)\n .map(([trait, entries]) => {\n const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0)\n const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n)\n const values = Object.fromEntries(\n Object.entries(entries).map(([value, traitValueCount]) => {\n const { p } = calculateBinomialParamsFromProbability(n, traitValueCount / n)\n const metrics: NftTraitMetrics = { binomial: { p }, count: traitValueCount }\n return [value, metrics]\n }),\n )\n return [trait, { metrics: { binomial: { p }, count: traitCount }, values }]\n }),\n )\n return { metadata: { attributes } }\n}\n","import { Interface } from '@ethersproject/abi'\nimport { Provider } from '@ethersproject/providers'\n\nexport const contractHasFunctions = async (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => {\n try {\n const bytecode = await provider.getCode(address, 'latest')\n for (let i = 0; i < functionNames.length; i++) {\n const nameSig = contractInterface.getSighash(functionNames[i]).substring(2)\n if (!bytecode.includes(nameSig)) {\n return false\n }\n return true\n }\n return false\n } catch (ex) {\n const error = ex as Error\n console.log(error)\n return false\n }\n}\n","import { BaseProvider } from '@ethersproject/providers'\nimport { AxiosJson } from '@xylabs/axios'\nimport { BigNumber as XyBigNumber } from '@xylabs/bignumber'\nimport { exists } from '@xylabs/exists'\nimport { getErc1822Status } from '@xyo-network/blockchain-erc1822-witness'\nimport { getErc1967Status } from '@xyo-network/blockchain-erc1967-witness'\nimport { NftInfo, NftMetadata, NftSchema, TokenType, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { checkIpfsUrl } from '@xyo-network/witness-blockchain-abstract'\n\nimport { tokenTypes } from './tokenTypes'\nimport { tryCall } from './tryCall'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\nconst hexBytesOnlyOnly = (value: string) => {\n return value.startsWith('0x') ? value.substring(2) : value\n}\n\nconst isHexZero = (value?: string) => {\n return value === undefined ? true : new XyBigNumber(hexBytesOnlyOnly(value), 'hex').eqn(0)\n}\n\nfunction range(size: number, startAt: number = 0): ReadonlyArray<number> {\n return [...Array(size).keys()].map((i) => i + startAt)\n}\n\nexport const getNftCollectionNfts = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: BaseProvider,\n types?: TokenType[],\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n maxNfts = 100,\n): Promise<NftInfo[]> => {\n try {\n const block = await provider.getBlockNumber()\n\n //Check if ERC-1967 Upgradeable\n const erc1967Status = await getErc1967Status(provider, contractAddress, block)\n\n //Check if ERC-1822 Upgradeable\n const erc1822Status = await getErc1822Status(provider, contractAddress, block)\n\n const implementation = isHexZero(erc1967Status.slots.implementation) ? erc1822Status.implementation : erc1967Status.implementation\n\n const axios = new AxiosJson({ timeout: 2000 })\n const enumerable = ERC721Enumerable__factory.connect(implementation, provider)\n const storage = ERC721URIStorage__factory.connect(implementation, provider)\n const supply1155 = ERC1155Supply__factory.connect(implementation, provider)\n const finalTypes = types ?? (await tokenTypes(provider, implementation))\n\n const maxNftsArray = range(maxNfts)\n\n const result: NftInfo[] = (\n await Promise.all(\n maxNftsArray.map(async (_value, i) => {\n const tokenId = (await tryCall(async () => (await enumerable.tokenByIndex(i, { blockTag: block })).toHexString())) ?? `${i}`\n if (tokenId !== undefined) {\n const supply = finalTypes.includes(toTokenType('ERC1155'))\n ? (await tryCall(async () => (await supply1155.totalSupply(tokenId, { blockTag: block })).toHexString())) ?? '0x01'\n : '0x01'\n const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, { blockTag: block }))\n const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : undefined\n let metadata: NftMetadata | undefined = undefined\n if (checkedMetaDataUri !== undefined) {\n try {\n metadata = (await axios.get(checkedMetaDataUri)).data\n } catch (ex) {\n const error = ex as Error\n console.error(`Get Metadata failed: ${error.message}`)\n }\n }\n\n const info: NftInfo = {\n address: contractAddress,\n chainId: provider.network.chainId,\n metadata,\n metadataUri,\n schema: NftSchema,\n supply,\n tokenId,\n type: finalTypes.at(0),\n types: finalTypes,\n }\n if (implementation !== contractAddress) {\n info.implementation = implementation\n }\n return info\n }\n }),\n )\n ).filter(exists)\n return result\n } catch (ex) {\n const error = ex as Error\n console.error(`getNftCollectionNfts failed: [${error.name}] ${error.message}`)\n console.log(error.stack)\n return []\n }\n}\n","import { Provider } from '@ethersproject/providers'\nimport { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC1155URIStorage__factory, IERC721Metadata__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { contractHasFunctions } from './contractHasFunctions'\n\nexport const isErc1155 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, ERC1155URIStorage__factory.createInterface(), ['uri'])\n}\n\nexport const isErc721 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, IERC721Metadata__factory.createInterface(), ['name', 'symbol', 'tokenURI'])\n}\n\nexport const tokenTypes = async (provider: Provider, address: string) => {\n const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)])\n const result: TokenType[] = []\n if (erc721) {\n result.push('ERC721')\n }\n if (erc1155) {\n result.push('ERC1155')\n }\n return result\n}\n","export const tryCall = async <T>(func: () => Promise<T>, name?: string): Promise<T | undefined> => {\n try {\n return await func()\n } catch (ex) {\n if (name) {\n const error = ex as Error\n console.log(`tryCall failed [${name}]: ${error.message}`)\n }\n return undefined\n }\n}\n"],"mappings":"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","names":["import_crypto_nft_payload_plugin","import_open_zeppelin_typechain","import_witness_blockchain_abstract","attributes","p","import_open_zeppelin_typechain","XyBigNumber"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import { createPayloadSetWitnessPlugin } from "@xyo-network/payloadset-plugin";
|
|
|
6
6
|
// src/Witness.ts
|
|
7
7
|
import { assertEx } from "@xylabs/assert";
|
|
8
8
|
import { EthAddress } from "@xylabs/eth-address";
|
|
9
|
-
import { AbstractWitness } from "@xyo-network/abstract-witness";
|
|
10
9
|
import { PayloadHasher } from "@xyo-network/core";
|
|
11
10
|
import {
|
|
12
11
|
isNftCollectionWitnessQuery,
|
|
@@ -14,7 +13,7 @@ import {
|
|
|
14
13
|
NftCollectionWitnessConfigSchema
|
|
15
14
|
} from "@xyo-network/crypto-nft-collection-payload-plugin";
|
|
16
15
|
import { ERC721Enumerable__factory as ERC721Enumerable__factory2 } from "@xyo-network/open-zeppelin-typechain";
|
|
17
|
-
import {
|
|
16
|
+
import { AbstractBlockchainWitness } from "@xyo-network/witness-blockchain-abstract";
|
|
18
17
|
|
|
19
18
|
// src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
|
|
20
19
|
var calculateAllPropertiesDistribution = (array) => {
|
|
@@ -93,11 +92,14 @@ var contractHasFunctions = async (provider, address, contractInterface, function
|
|
|
93
92
|
};
|
|
94
93
|
|
|
95
94
|
// src/lib/getNftCollectionNfts.ts
|
|
95
|
+
import { AxiosJson } from "@xylabs/axios";
|
|
96
|
+
import { BigNumber as XyBigNumber } from "@xylabs/bignumber";
|
|
96
97
|
import { exists } from "@xylabs/exists";
|
|
97
|
-
import {
|
|
98
|
+
import { getErc1822Status } from "@xyo-network/blockchain-erc1822-witness";
|
|
99
|
+
import { getErc1967Status } from "@xyo-network/blockchain-erc1967-witness";
|
|
98
100
|
import { NftSchema, toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
99
101
|
import { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
100
|
-
import { checkIpfsUrl
|
|
102
|
+
import { checkIpfsUrl } from "@xyo-network/witness-blockchain-abstract";
|
|
101
103
|
|
|
102
104
|
// src/lib/tokenTypes.ts
|
|
103
105
|
import { ERC1155URIStorage__factory, IERC721Metadata__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
@@ -134,12 +136,21 @@ var tryCall = async (func, name) => {
|
|
|
134
136
|
|
|
135
137
|
// src/lib/getNftCollectionNfts.ts
|
|
136
138
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
139
|
+
var hexBytesOnlyOnly = (value) => {
|
|
140
|
+
return value.startsWith("0x") ? value.substring(2) : value;
|
|
141
|
+
};
|
|
142
|
+
var isHexZero = (value) => {
|
|
143
|
+
return value === void 0 ? true : new XyBigNumber(hexBytesOnlyOnly(value), "hex").eqn(0);
|
|
144
|
+
};
|
|
137
145
|
function range(size, startAt = 0) {
|
|
138
146
|
return [...Array(size).keys()].map((i) => i + startAt);
|
|
139
147
|
}
|
|
140
148
|
var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
|
|
141
149
|
try {
|
|
142
|
-
const
|
|
150
|
+
const block = await provider.getBlockNumber();
|
|
151
|
+
const erc1967Status = await getErc1967Status(provider, contractAddress, block);
|
|
152
|
+
const erc1822Status = await getErc1822Status(provider, contractAddress, block);
|
|
153
|
+
const implementation = isHexZero(erc1967Status.slots.implementation) ? erc1822Status.implementation : erc1967Status.implementation;
|
|
143
154
|
const axios = new AxiosJson({ timeout: 2e3 });
|
|
144
155
|
const enumerable = ERC721Enumerable__factory.connect(implementation, provider);
|
|
145
156
|
const storage = ERC721URIStorage__factory.connect(implementation, provider);
|
|
@@ -148,10 +159,10 @@ var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 10
|
|
|
148
159
|
const maxNftsArray = range(maxNfts);
|
|
149
160
|
const result = (await Promise.all(
|
|
150
161
|
maxNftsArray.map(async (_value, i) => {
|
|
151
|
-
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString()) ?? `${i}`;
|
|
162
|
+
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i, { blockTag: block })).toHexString()) ?? `${i}`;
|
|
152
163
|
if (tokenId !== void 0) {
|
|
153
|
-
const supply = finalTypes.includes(toTokenType("ERC1155")) ? await tryCall(async () => (await supply1155.totalSupply(tokenId)).toHexString()) ?? "0x01" : "0x01";
|
|
154
|
-
const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId));
|
|
164
|
+
const supply = finalTypes.includes(toTokenType("ERC1155")) ? await tryCall(async () => (await supply1155.totalSupply(tokenId, { blockTag: block })).toHexString()) ?? "0x01" : "0x01";
|
|
165
|
+
const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, { blockTag: block }));
|
|
155
166
|
const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : void 0;
|
|
156
167
|
let metadata = void 0;
|
|
157
168
|
if (checkedMetaDataUri !== void 0) {
|
|
@@ -198,20 +209,16 @@ function resolvedValue(settled, assert) {
|
|
|
198
209
|
}
|
|
199
210
|
return settled.status === "fulfilled" ? settled.value : void 0;
|
|
200
211
|
}
|
|
201
|
-
var CryptoNftCollectionWitness = class extends
|
|
212
|
+
var CryptoNftCollectionWitness = class extends AbstractBlockchainWitness {
|
|
202
213
|
static configSchemas = [NftCollectionWitnessConfigSchema];
|
|
203
|
-
providers = {};
|
|
204
|
-
getProvider(chainId) {
|
|
205
|
-
this.providers[chainId] = this.providers[chainId] ?? getProviderFromEnv(chainId);
|
|
206
|
-
return this.providers[chainId];
|
|
207
|
-
}
|
|
208
214
|
async observeHandler(payloads) {
|
|
209
215
|
await this.started("throw");
|
|
216
|
+
await this.getProviders();
|
|
210
217
|
const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? [];
|
|
211
218
|
const observations = await Promise.all(
|
|
212
219
|
queries.map(async (query) => {
|
|
213
220
|
const chainId = assertEx(query?.chainId || this.config.chainId, "params.chainId is required");
|
|
214
|
-
const provider = this.getProvider(
|
|
221
|
+
const provider = await this.getProvider(true, true);
|
|
215
222
|
const address = assertEx(
|
|
216
223
|
EthAddress.parse(assertEx(query?.address || this.config.address, "params.address is required")),
|
|
217
224
|
"Failed to parse params.address"
|