@xyo-network/crypto-nft-collection-witness-plugin 2.78.0 → 2.78.2
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 +117 -41
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +115 -39
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lib/getNftCollectionCount.d.cts +1 -1
- package/dist/browser/lib/getNftCollectionCount.d.cts.map +1 -1
- package/dist/browser/lib/getNftCollectionCount.d.mts +1 -1
- package/dist/browser/lib/getNftCollectionCount.d.mts.map +1 -1
- package/dist/browser/lib/getNftCollectionCount.d.ts +1 -1
- package/dist/browser/lib/getNftCollectionCount.d.ts.map +1 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.cts +3 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.cts.map +1 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.mts +3 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.mts.map +1 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.ts +3 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.ts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.cts +8 -1
- package/dist/browser/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.mts +8 -1
- package/dist/browser/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.ts +8 -1
- package/dist/browser/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/dist/browser/lib/getProvider.d.cts +3 -0
- package/dist/browser/lib/getProvider.d.cts.map +1 -0
- package/dist/browser/lib/getProvider.d.mts +3 -0
- package/dist/browser/lib/getProvider.d.mts.map +1 -0
- package/dist/browser/lib/getProvider.d.ts +3 -0
- package/dist/browser/lib/getProvider.d.ts.map +1 -0
- package/dist/node/index.js +119 -41
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +115 -39
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/lib/getNftCollectionCount.d.cts +1 -1
- package/dist/node/lib/getNftCollectionCount.d.cts.map +1 -1
- package/dist/node/lib/getNftCollectionCount.d.mts +1 -1
- package/dist/node/lib/getNftCollectionCount.d.mts.map +1 -1
- package/dist/node/lib/getNftCollectionCount.d.ts +1 -1
- package/dist/node/lib/getNftCollectionCount.d.ts.map +1 -1
- package/dist/node/lib/getNftCollectionMetadata.d.cts +3 -1
- package/dist/node/lib/getNftCollectionMetadata.d.cts.map +1 -1
- package/dist/node/lib/getNftCollectionMetadata.d.mts +3 -1
- package/dist/node/lib/getNftCollectionMetadata.d.mts.map +1 -1
- package/dist/node/lib/getNftCollectionMetadata.d.ts +3 -1
- package/dist/node/lib/getNftCollectionMetadata.d.ts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.cts +8 -1
- package/dist/node/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.mts +8 -1
- package/dist/node/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.ts +8 -1
- package/dist/node/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/dist/node/lib/getProvider.d.cts +3 -0
- package/dist/node/lib/getProvider.d.cts.map +1 -0
- package/dist/node/lib/getProvider.d.mts +3 -0
- package/dist/node/lib/getProvider.d.mts.map +1 -0
- package/dist/node/lib/getProvider.d.ts +3 -0
- package/dist/node/lib/getProvider.d.ts.map +1 -0
- package/package.json +12 -12
- package/src/Witness.ts +3 -3
- package/src/lib/getNftCollectionCount.ts +5 -18
- package/src/lib/getNftCollectionMetadata.ts +38 -18
- package/src/lib/getNftCollectionNfts.ts +62 -31
- package/src/lib/getProvider.ts +17 -0
package/dist/node/index.mjs
CHANGED
|
@@ -75,7 +75,22 @@ var getNftCollectionMetrics = (nfts) => {
|
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
// src/lib/getNftCollectionCount.ts
|
|
78
|
-
import {
|
|
78
|
+
import { ERC721Enumerable__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
79
|
+
|
|
80
|
+
// src/lib/getProvider.ts
|
|
81
|
+
import { InfuraProvider, WebSocketProvider } from "@ethersproject/providers";
|
|
82
|
+
var getProviderFromEnv = (chainId = "homestead") => {
|
|
83
|
+
const infuraWssUri = process.env.INFURA_WSS_URI;
|
|
84
|
+
const infuraProvider = new InfuraProvider("homestead", {
|
|
85
|
+
projectId: process.env.INFURA_PROJECT_ID,
|
|
86
|
+
projectSecret: process.env.INFURA_PROJECT_SECRET
|
|
87
|
+
});
|
|
88
|
+
const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : void 0;
|
|
89
|
+
const quickNodeUri = process.env.QUICKNODE_WSS_URI;
|
|
90
|
+
const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : void 0;
|
|
91
|
+
const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
|
|
92
|
+
return provider;
|
|
93
|
+
};
|
|
79
94
|
|
|
80
95
|
// src/lib/nonEvaluableContractAddresses.ts
|
|
81
96
|
var nonEvaluableContractAddresses = [
|
|
@@ -84,56 +99,115 @@ var nonEvaluableContractAddresses = [
|
|
|
84
99
|
].map((address) => address.toUpperCase());
|
|
85
100
|
|
|
86
101
|
// src/lib/getNftCollectionCount.ts
|
|
87
|
-
var getNftCollectionCount = async (contractAddress, chainId
|
|
102
|
+
var getNftCollectionCount = async (contractAddress, chainId) => {
|
|
88
103
|
if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
|
|
89
104
|
throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
|
|
90
105
|
}
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
return total;
|
|
106
|
+
const provider = getProviderFromEnv(chainId);
|
|
107
|
+
const contract = ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
108
|
+
return (await contract.totalSupply()).toNumber();
|
|
95
109
|
};
|
|
96
110
|
|
|
97
111
|
// src/lib/getNftCollectionMetadata.ts
|
|
98
|
-
import {
|
|
99
|
-
import {
|
|
100
|
-
|
|
112
|
+
import { ERC721Enumerable__factory as ERC721Enumerable__factory2, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
113
|
+
import { constants } from "ethers";
|
|
114
|
+
function getInterfaceID(contractInterface) {
|
|
115
|
+
let interfaceID = constants.Zero;
|
|
116
|
+
const functions = Object.keys(contractInterface.functions);
|
|
117
|
+
for (let i = 0; i < functions.length; i++) {
|
|
118
|
+
interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
|
|
119
|
+
}
|
|
120
|
+
return interfaceID.toHexString();
|
|
121
|
+
}
|
|
122
|
+
var getNftCollectionMetadata = async (contractAddress, chainId) => {
|
|
101
123
|
if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
|
|
102
124
|
throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
|
|
103
125
|
}
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
126
|
+
const provider = getProviderFromEnv(chainId);
|
|
127
|
+
const contract721 = ERC721Enumerable__factory2.connect(contractAddress, provider);
|
|
128
|
+
const contract1155 = ERC1155__factory.connect(contractAddress, provider);
|
|
129
|
+
let name = "";
|
|
130
|
+
try {
|
|
131
|
+
name = await contract721.name();
|
|
132
|
+
} catch (ex) {
|
|
133
|
+
const error = ex;
|
|
134
|
+
console.log(`name: ${error.message}`);
|
|
135
|
+
}
|
|
136
|
+
let symbol = "";
|
|
137
|
+
try {
|
|
138
|
+
symbol = await contract721.symbol();
|
|
139
|
+
} catch (ex) {
|
|
140
|
+
const error = ex;
|
|
141
|
+
console.log(`symbol: ${error.message}`);
|
|
142
|
+
}
|
|
143
|
+
let is1155 = false;
|
|
144
|
+
try {
|
|
145
|
+
is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)));
|
|
146
|
+
} catch (ex) {
|
|
147
|
+
const error = ex;
|
|
148
|
+
console.log(`is1155: ${error.message}`);
|
|
149
|
+
is1155 = false;
|
|
150
|
+
}
|
|
151
|
+
return { address: contractAddress, chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
|
|
109
152
|
};
|
|
110
153
|
|
|
111
154
|
// src/lib/getNftCollectionNfts.ts
|
|
112
|
-
import {
|
|
113
|
-
import { NftSchema, toTokenType
|
|
114
|
-
|
|
155
|
+
import { AxiosJson } from "@xyo-network/axios";
|
|
156
|
+
import { NftSchema, toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
157
|
+
import { ERC721Enumerable__factory as ERC721Enumerable__factory3, ERC721URIStorage__factory, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
158
|
+
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
159
|
+
var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
160
|
+
const url = new URL(urlToCheck);
|
|
161
|
+
let protocol = url.protocol;
|
|
162
|
+
let host = url.host;
|
|
163
|
+
let path = url.pathname;
|
|
164
|
+
const query = url.search;
|
|
165
|
+
if (protocol === "ipfs:") {
|
|
166
|
+
protocol = "https:";
|
|
167
|
+
host = ipfsGateway2;
|
|
168
|
+
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
169
|
+
const root = `${protocol}//${host}/${path}`;
|
|
170
|
+
return (query == null ? void 0 : query.length) > 0 ? `${root}?${query}` : root;
|
|
171
|
+
} else {
|
|
172
|
+
return urlToCheck;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
var getNftCollectionNfts = async (contractAddress, chainId, maxNfts = 100) => {
|
|
115
176
|
if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
|
|
116
177
|
throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
|
|
117
178
|
}
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
179
|
+
const axios = new AxiosJson({ timeout: 2e3 });
|
|
180
|
+
const provider = getProviderFromEnv(chainId);
|
|
181
|
+
const enumerable = ERC721Enumerable__factory3.connect(contractAddress, provider);
|
|
182
|
+
const storage = ERC721URIStorage__factory.connect(contractAddress, provider);
|
|
183
|
+
const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider);
|
|
184
|
+
const result = [];
|
|
185
|
+
const { type: nftType } = await getNftCollectionMetadata(contractAddress, chainId);
|
|
186
|
+
for (let i = 0; i < maxNfts; i++) {
|
|
187
|
+
const tokenId = (await enumerable.tokenByIndex(i)).toHexString();
|
|
188
|
+
const supply = nftType === toTokenType("ERC11155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
|
|
189
|
+
const metadataUri = await storage.tokenURI(tokenId);
|
|
190
|
+
const checkedMetaDataUri = checkIpfsUrl(metadataUri, ipfsGateway);
|
|
191
|
+
let metadata = void 0;
|
|
192
|
+
try {
|
|
193
|
+
metadata = (await axios.get(checkedMetaDataUri)).data;
|
|
194
|
+
} catch (ex) {
|
|
195
|
+
const error = ex;
|
|
196
|
+
console.error(error.message);
|
|
197
|
+
}
|
|
198
|
+
const info = {
|
|
199
|
+
address: contractAddress,
|
|
200
|
+
chainId,
|
|
201
|
+
metadata,
|
|
202
|
+
metadataUri,
|
|
203
|
+
schema: NftSchema,
|
|
204
|
+
supply,
|
|
205
|
+
tokenId,
|
|
206
|
+
type: nftType
|
|
207
|
+
};
|
|
208
|
+
result.push(info);
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
137
211
|
};
|
|
138
212
|
|
|
139
213
|
// src/Witness.ts
|
|
@@ -153,9 +227,9 @@ var CryptoNftCollectionWitness = class extends AbstractWitness {
|
|
|
153
227
|
const chainId = assertEx((query == null ? void 0 : query.chainId) || this.config.chainId, "params.chainId is required");
|
|
154
228
|
const maxNfts = (query == null ? void 0 : query.maxNfts) || defaultMaxNfts;
|
|
155
229
|
const [info, total, nfts, archivist] = await Promise.all([
|
|
156
|
-
getNftCollectionMetadata(address, chainId
|
|
157
|
-
getNftCollectionCount(address, chainId
|
|
158
|
-
getNftCollectionNfts(address, chainId,
|
|
230
|
+
getNftCollectionMetadata(address, chainId),
|
|
231
|
+
getNftCollectionCount(address, chainId),
|
|
232
|
+
getNftCollectionNfts(address, chainId, maxNfts),
|
|
159
233
|
this.writeArchivist()
|
|
160
234
|
]);
|
|
161
235
|
const metrics = getNftCollectionMetrics(nfts);
|
|
@@ -189,7 +263,9 @@ var src_default = CryptoNftCollectionWitnessPlugin;
|
|
|
189
263
|
export {
|
|
190
264
|
CryptoNftCollectionWitness,
|
|
191
265
|
CryptoNftCollectionWitnessPlugin,
|
|
266
|
+
checkIpfsUrl,
|
|
192
267
|
src_default as default,
|
|
268
|
+
getInterfaceID,
|
|
193
269
|
getNftCollectionCount,
|
|
194
270
|
getNftCollectionMetadata,
|
|
195
271
|
getNftCollectionMetrics,
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../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/getNftCollectionCount.ts","../../src/lib/nonEvaluableContractAddresses.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getNftCollectionNfts.ts","../../src/index.ts"],"sourcesContent":["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 { 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 { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftCollectionCount, getNftCollectionMetadata, getNftCollectionMetrics, getNftCollectionNfts } from './lib'\n\nexport type CryptoNftCollectionWitnessParams = WitnessParams<AnyConfigSchema<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\nexport class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractWitness<\n TParams,\n NftCollectionWitnessQuery,\n NftCollectionInfo\n> {\n static override configSchemas = [NftCollectionWitnessConfigSchema]\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 address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [info, total, nfts, archivist] = await Promise.all([\n getNftCollectionMetadata(address, chainId, this.account.private.hex),\n getNftCollectionCount(address, chainId, this.account.private.hex),\n getNftCollectionNfts(address, chainId, this.account.private.hex, maxNfts),\n this.writeArchivist(),\n ])\n const metrics = getNftCollectionMetrics(nfts)\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 = { ...info, metrics, schema: NftCollectionSchema, sources, total }\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 { Auth, SDK } from '@infura/sdk'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionCount = 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 chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n): Promise<number> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const opts: ContractAddressOptions = { contractAddress }\n const { total } = await sdk.api.getNFTsForCollection(opts)\n return total\n}\n","/**\n * These contracts are not evaluable for some\n * reason (too large, nonsensical, etc.)\n */\nexport const nonEvaluableContractAddresses = [\n // ENS\n '0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',\n].map((address) => address.toUpperCase())\n","import { Auth, SDK } from '@infura/sdk'\nimport { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionMetadata = 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 chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n): Promise<Omit<NftCollectionMetadata, 'total'>> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const opts: ContractAddressOptions = { contractAddress }\n const { name, symbol, tokenType } = await sdk.api.getContractMetadata(opts)\n const type = toTokenType(tokenType)\n return { address: contractAddress, chainId, name, symbol, type }\n}\n","import { Auth, SDK } from '@infura/sdk'\nimport { NftInfo, NftInfoFields, NftSchema, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\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 chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\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 if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const nfts: NftInfoFields[] = []\n let cursor: string | undefined = undefined\n do {\n const opts: ContractAddressOptions = { contractAddress, cursor }\n const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTsForCollection(opts)\n const batch: NftInfoFields[] = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {\n const { contract: address, type: tokenType, ...rest } = asset\n const type = toTokenType(tokenType)\n return { address, chainId, type, ...rest }\n })\n nfts.push(...batch)\n cursor = nextCursor\n if (nfts.length >= total || !cursor) break\n } while (nfts.length < maxNfts)\n return nfts.map((nft) => {\n return { ...nft, schema: NftSchema }\n })\n}\n","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"],"mappings":"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","names":["NftSchema","attributes","p","Auth","SDK","SDK","Auth","Auth","SDK","toTokenType","SDK","Auth","toTokenType","NftSchema"]}
|
|
1
|
+
{"version":3,"sources":["../../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/getNftCollectionCount.ts","../../src/lib/getProvider.ts","../../src/lib/nonEvaluableContractAddresses.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getNftCollectionNfts.ts","../../src/index.ts"],"sourcesContent":["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 { 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 { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftCollectionCount, getNftCollectionMetadata, getNftCollectionMetrics, getNftCollectionNfts } from './lib'\n\nexport type CryptoNftCollectionWitnessParams = WitnessParams<AnyConfigSchema<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\nexport class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams> extends AbstractWitness<\n TParams,\n NftCollectionWitnessQuery,\n NftCollectionInfo\n> {\n static override configSchemas = [NftCollectionWitnessConfigSchema]\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 address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [info, total, nfts, archivist] = await Promise.all([\n getNftCollectionMetadata(address, chainId),\n getNftCollectionCount(address, chainId),\n getNftCollectionNfts(address, chainId, maxNfts),\n this.writeArchivist(),\n ])\n const metrics = getNftCollectionMetrics(nfts)\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 = { ...info, metrics, schema: NftCollectionSchema, sources, total }\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 { ERC721Enumerable__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getProviderFromEnv } from './getProvider'\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\nexport const getNftCollectionCount = 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 chainId: number,\n): Promise<number> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const provider = getProviderFromEnv(chainId)\n const contract = ERC721Enumerable__factory.connect(contractAddress, provider)\n return (await contract.totalSupply()).toNumber()\n}\n","import { InfuraProvider, WebSocketProvider } from '@ethersproject/providers'\n\nexport const getProviderFromEnv = (chainId: string | number = 'homestead') => {\n const infuraWssUri = process.env.INFURA_WSS_URI\n const infuraProvider = new InfuraProvider('homestead', {\n projectId: process.env.INFURA_PROJECT_ID,\n projectSecret: process.env.INFURA_PROJECT_SECRET,\n })\n\n const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : undefined\n\n const quickNodeUri = process.env.QUICKNODE_WSS_URI\n const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : undefined\n\n const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider\n return provider\n}\n","/**\n * These contracts are not evaluable for some\n * reason (too large, nonsensical, etc.)\n */\nexport const nonEvaluableContractAddresses = [\n // ENS\n '0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',\n].map((address) => address.toUpperCase())\n","import { Interface } from '@ethersproject/abi'\nimport { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { ERC721Enumerable__factory, ERC1155__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { constants } from 'ethers'\n\nimport { getProviderFromEnv } from './getProvider'\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\nexport function getInterfaceID(contractInterface: Interface) {\n let interfaceID = constants.Zero\n const functions: string[] = Object.keys(contractInterface.functions)\n for (let i = 0; i < functions.length; i++) {\n interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]))\n }\n\n return interfaceID.toHexString()\n}\n\nexport const getNftCollectionMetadata = 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 chainId: number,\n): Promise<Omit<NftCollectionMetadata, 'total'>> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const provider = getProviderFromEnv(chainId)\n const contract721 = ERC721Enumerable__factory.connect(contractAddress, provider)\n const contract1155 = ERC1155__factory.connect(contractAddress, provider)\n let name: string = ''\n try {\n name = await contract721.name()\n } catch (ex) {\n const error = ex as Error\n console.log(`name: ${error.message}`)\n }\n let symbol: string = ''\n try {\n symbol = await contract721.symbol()\n } catch (ex) {\n const error = ex as Error\n console.log(`symbol: ${error.message}`)\n }\n let is1155: boolean = false\n try {\n is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)))\n } catch (ex) {\n const error = ex as Error\n console.log(`is1155: ${error.message}`)\n is1155 = false\n }\n return { address: contractAddress, chainId, name, symbol, type: is1155 ? 'ERC1155' : 'ERC721' }\n}\n","import { AxiosJson } from '@xyo-network/axios'\nimport { NftInfo, NftMetadata, NftSchema, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getNftCollectionMetadata } from './getNftCollectionMetadata'\nimport { getProviderFromEnv } from './getProvider'\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\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 chainId: number,\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 if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const axios = new AxiosJson({ timeout: 2000 })\n const provider = getProviderFromEnv(chainId)\n const enumerable = ERC721Enumerable__factory.connect(contractAddress, provider)\n const storage = ERC721URIStorage__factory.connect(contractAddress, provider)\n const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider)\n const result: NftInfo[] = []\n const { type: nftType } = await getNftCollectionMetadata(contractAddress, chainId)\n\n for (let i = 0; i < maxNfts; i++) {\n const tokenId = (await enumerable.tokenByIndex(i)).toHexString()\n const supply = nftType === toTokenType('ERC11155') ? (await supply1155.totalSupply(tokenId)).toHexString() : '0x01'\n const metadataUri = await storage.tokenURI(tokenId)\n const checkedMetaDataUri = checkIpfsUrl(metadataUri, ipfsGateway)\n let metadata: NftMetadata | undefined = undefined\n try {\n metadata = (await axios.get(checkedMetaDataUri)).data\n } catch (ex) {\n const error = ex as Error\n console.error(error.message)\n }\n\n const info: NftInfo = {\n address: contractAddress,\n chainId,\n metadata,\n metadataUri,\n schema: NftSchema,\n supply,\n tokenId,\n type: nftType,\n }\n result.push(info)\n }\n return result\n}\n","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"],"mappings":"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","names":["NftSchema","attributes","p","ERC721Enumerable__factory","ERC721Enumerable__factory","ERC721Enumerable__factory","ipfsGateway","ERC721Enumerable__factory","NftSchema"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const getNftCollectionCount: (contractAddress: string, chainId: number
|
|
1
|
+
export declare const getNftCollectionCount: (contractAddress: string, chainId: number) => Promise<number>;
|
|
2
2
|
//# sourceMappingURL=getNftCollectionCount.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionCount.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionCount.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionCount.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionCount.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,oBAIf,MAAM,WAId,MAAM,KACd,QAAQ,MAAM,CAOhB,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const getNftCollectionCount: (contractAddress: string, chainId: number
|
|
1
|
+
export declare const getNftCollectionCount: (contractAddress: string, chainId: number) => Promise<number>;
|
|
2
2
|
//# sourceMappingURL=getNftCollectionCount.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionCount.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionCount.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionCount.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionCount.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,oBAIf,MAAM,WAId,MAAM,KACd,QAAQ,MAAM,CAOhB,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const getNftCollectionCount: (contractAddress: string, chainId: number
|
|
1
|
+
export declare const getNftCollectionCount: (contractAddress: string, chainId: number) => Promise<number>;
|
|
2
2
|
//# sourceMappingURL=getNftCollectionCount.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionCount.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionCount.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionCount.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionCount.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,oBAIf,MAAM,WAId,MAAM,KACd,QAAQ,MAAM,CAOhB,CAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
1
2
|
import { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin';
|
|
2
|
-
export declare
|
|
3
|
+
export declare function getInterfaceID(contractInterface: Interface): string;
|
|
4
|
+
export declare const getNftCollectionMetadata: (contractAddress: string, chainId: number) => Promise<Omit<NftCollectionMetadata, 'total'>>;
|
|
3
5
|
//# sourceMappingURL=getNftCollectionMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionMetadata.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AAOzF,wBAAgB,cAAc,CAAC,iBAAiB,EAAE,SAAS,UAQ1D;AAED,eAAO,MAAM,wBAAwB,oBAIlB,MAAM,WAId,MAAM,KACd,QAAQ,KAAK,qBAAqB,EAAE,OAAO,CAAC,CA8B9C,CAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
1
2
|
import { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin';
|
|
2
|
-
export declare
|
|
3
|
+
export declare function getInterfaceID(contractInterface: Interface): string;
|
|
4
|
+
export declare const getNftCollectionMetadata: (contractAddress: string, chainId: number) => Promise<Omit<NftCollectionMetadata, 'total'>>;
|
|
3
5
|
//# sourceMappingURL=getNftCollectionMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionMetadata.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AAOzF,wBAAgB,cAAc,CAAC,iBAAiB,EAAE,SAAS,UAQ1D;AAED,eAAO,MAAM,wBAAwB,oBAIlB,MAAM,WAId,MAAM,KACd,QAAQ,KAAK,qBAAqB,EAAE,OAAO,CAAC,CA8B9C,CAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
1
2
|
import { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin';
|
|
2
|
-
export declare
|
|
3
|
+
export declare function getInterfaceID(contractInterface: Interface): string;
|
|
4
|
+
export declare const getNftCollectionMetadata: (contractAddress: string, chainId: number) => Promise<Omit<NftCollectionMetadata, 'total'>>;
|
|
3
5
|
//# sourceMappingURL=getNftCollectionMetadata.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionMetadata.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AAOzF,wBAAgB,cAAc,CAAC,iBAAiB,EAAE,SAAS,UAQ1D;AAED,eAAO,MAAM,wBAAwB,oBAIlB,MAAM,WAId,MAAM,KACd,QAAQ,KAAK,qBAAqB,EAAE,OAAO,CAAC,CA8B9C,CAAA"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { NftInfo } from '@xyo-network/crypto-nft-payload-plugin';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
4
|
+
* @param urlToCheck The URL to check
|
|
5
|
+
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
6
|
+
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
7
|
+
*/
|
|
8
|
+
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
9
|
+
export declare const getNftCollectionNfts: (contractAddress: string, chainId: number, maxNfts?: number) => Promise<NftInfo[]>;
|
|
3
10
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAuC,MAAM,wCAAwC,CAAA;AASrG;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,eAAe,MAAM,WAenE,CAAA;AAED,eAAO,MAAM,oBAAoB,oBAId,MAAM,WAId,MAAM,uBAOd,QAAQ,OAAO,EAAE,CAsCnB,CAAA"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { NftInfo } from '@xyo-network/crypto-nft-payload-plugin';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
4
|
+
* @param urlToCheck The URL to check
|
|
5
|
+
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
6
|
+
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
7
|
+
*/
|
|
8
|
+
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
9
|
+
export declare const getNftCollectionNfts: (contractAddress: string, chainId: number, maxNfts?: number) => Promise<NftInfo[]>;
|
|
3
10
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAuC,MAAM,wCAAwC,CAAA;AASrG;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,eAAe,MAAM,WAenE,CAAA;AAED,eAAO,MAAM,oBAAoB,oBAId,MAAM,WAId,MAAM,uBAOd,QAAQ,OAAO,EAAE,CAsCnB,CAAA"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { NftInfo } from '@xyo-network/crypto-nft-payload-plugin';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
4
|
+
* @param urlToCheck The URL to check
|
|
5
|
+
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
6
|
+
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
7
|
+
*/
|
|
8
|
+
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
9
|
+
export declare const getNftCollectionNfts: (contractAddress: string, chainId: number, maxNfts?: number) => Promise<NftInfo[]>;
|
|
3
10
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAuC,MAAM,wCAAwC,CAAA;AASrG;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,eAAe,MAAM,WAenE,CAAA;AAED,eAAO,MAAM,oBAAoB,oBAId,MAAM,WAId,MAAM,uBAOd,QAAQ,OAAO,EAAE,CAsCnB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/getProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5E,eAAO,MAAM,kBAAkB,aAAa,MAAM,GAAG,MAAM,uCAc1D,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/getProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5E,eAAO,MAAM,kBAAkB,aAAa,MAAM,GAAG,MAAM,uCAc1D,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getProvider.d.ts","sourceRoot":"","sources":["../../../src/lib/getProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5E,eAAO,MAAM,kBAAkB,aAAa,MAAM,GAAG,MAAM,uCAc1D,CAAA"}
|
package/package.json
CHANGED
|
@@ -10,24 +10,24 @@
|
|
|
10
10
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@
|
|
13
|
+
"@ethersproject/abi": "^5.7.0",
|
|
14
14
|
"@xylabs/assert": "^2.13.3",
|
|
15
15
|
"@xylabs/eth-address": "^2.13.3",
|
|
16
|
-
"@xyo-network/abstract-witness": "~2.78.
|
|
17
|
-
"@xyo-network/core": "~2.78.
|
|
18
|
-
"@xyo-network/crypto-nft-collection-payload-plugin": "~2.78.
|
|
19
|
-
"@xyo-network/crypto-nft-payload-plugin": "~2.78.
|
|
20
|
-
"@xyo-network/module-model": "~2.78.
|
|
21
|
-
"@xyo-network/payload-model": "~2.78.
|
|
22
|
-
"@xyo-network/payloadset-plugin": "~2.78.
|
|
23
|
-
"@xyo-network/witness-model": "~2.78.
|
|
16
|
+
"@xyo-network/abstract-witness": "~2.78.2",
|
|
17
|
+
"@xyo-network/core": "~2.78.2",
|
|
18
|
+
"@xyo-network/crypto-nft-collection-payload-plugin": "~2.78.2",
|
|
19
|
+
"@xyo-network/crypto-nft-payload-plugin": "~2.78.2",
|
|
20
|
+
"@xyo-network/module-model": "~2.78.2",
|
|
21
|
+
"@xyo-network/payload-model": "~2.78.2",
|
|
22
|
+
"@xyo-network/payloadset-plugin": "~2.78.2",
|
|
23
|
+
"@xyo-network/witness-model": "~2.78.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@xylabs/jest-helpers": "^2.13.3",
|
|
27
27
|
"@xylabs/ts-scripts-yarn3": "^3.1.13",
|
|
28
28
|
"@xylabs/tsconfig": "^3.1.13",
|
|
29
|
-
"@xyo-network/account": "~2.78.
|
|
30
|
-
"@xyo-network/account-model": "~2.78.
|
|
29
|
+
"@xyo-network/account": "~2.78.2",
|
|
30
|
+
"@xyo-network/account-model": "~2.78.2",
|
|
31
31
|
"ethers": "^5.7.2",
|
|
32
32
|
"jest": "^29.7.0",
|
|
33
33
|
"typescript": "^5.2.2"
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
|
|
73
73
|
},
|
|
74
74
|
"sideEffects": false,
|
|
75
|
-
"version": "2.78.
|
|
75
|
+
"version": "2.78.2"
|
|
76
76
|
}
|
package/src/Witness.ts
CHANGED
|
@@ -45,9 +45,9 @@ export class CryptoNftCollectionWitness<TParams extends CryptoNftCollectionWitne
|
|
|
45
45
|
const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')
|
|
46
46
|
const maxNfts = query?.maxNfts || defaultMaxNfts
|
|
47
47
|
const [info, total, nfts, archivist] = await Promise.all([
|
|
48
|
-
getNftCollectionMetadata(address, chainId
|
|
49
|
-
getNftCollectionCount(address, chainId
|
|
50
|
-
getNftCollectionNfts(address, chainId,
|
|
48
|
+
getNftCollectionMetadata(address, chainId),
|
|
49
|
+
getNftCollectionCount(address, chainId),
|
|
50
|
+
getNftCollectionNfts(address, chainId, maxNfts),
|
|
51
51
|
this.writeArchivist(),
|
|
52
52
|
])
|
|
53
53
|
const metrics = getNftCollectionMetrics(nfts)
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ERC721Enumerable__factory } from '@xyo-network/open-zeppelin-typechain'
|
|
2
2
|
|
|
3
|
+
import { getProviderFromEnv } from './getProvider'
|
|
3
4
|
import { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'
|
|
4
5
|
|
|
5
|
-
type ContractAddressOptions = {
|
|
6
|
-
contractAddress: string
|
|
7
|
-
cursor?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
6
|
export const getNftCollectionCount = async (
|
|
11
7
|
/**
|
|
12
8
|
* The address of the NFT contract to search for
|
|
@@ -16,20 +12,11 @@ export const getNftCollectionCount = async (
|
|
|
16
12
|
* The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on
|
|
17
13
|
*/
|
|
18
14
|
chainId: number,
|
|
19
|
-
// /**
|
|
20
|
-
// * The ethers provider to use to search for NFTs
|
|
21
|
-
// */
|
|
22
|
-
// provider: ExternalProvider | JsonRpcFetchFunc,
|
|
23
|
-
/**
|
|
24
|
-
* The private key of the wallet to use to search for NFTs
|
|
25
|
-
*/
|
|
26
|
-
privateKey: string,
|
|
27
15
|
): Promise<number> => {
|
|
28
16
|
if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
|
|
29
17
|
throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)
|
|
30
18
|
}
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
return total
|
|
19
|
+
const provider = getProviderFromEnv(chainId)
|
|
20
|
+
const contract = ERC721Enumerable__factory.connect(contractAddress, provider)
|
|
21
|
+
return (await contract.totalSupply()).toNumber()
|
|
35
22
|
}
|