@xyo-network/crypto-nft-collection-witness-plugin 2.79.2 → 2.79.4
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 +45 -51
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +43 -49
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.cts +0 -7
- package/dist/browser/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.mts +0 -7
- package/dist/browser/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.ts +0 -7
- package/dist/browser/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/dist/node/index.js +45 -52
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +43 -49
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.cts +0 -7
- package/dist/node/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.mts +0 -7
- package/dist/node/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.ts +0 -7
- package/dist/node/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/lib/getNftCollectionNfts.ts +51 -57
package/dist/browser/index.cjs
CHANGED
|
@@ -22,7 +22,6 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
CryptoNftCollectionWitness: () => CryptoNftCollectionWitness,
|
|
24
24
|
CryptoNftCollectionWitnessPlugin: () => CryptoNftCollectionWitnessPlugin,
|
|
25
|
-
checkIpfsUrl: () => checkIpfsUrl,
|
|
26
25
|
contractHasFunctions: () => contractHasFunctions,
|
|
27
26
|
default: () => src_default,
|
|
28
27
|
getNftCollectionMetrics: () => getNftCollectionMetrics,
|
|
@@ -45,7 +44,7 @@ var import_abstract_witness = require("@xyo-network/abstract-witness");
|
|
|
45
44
|
var import_core = require("@xyo-network/core");
|
|
46
45
|
var import_crypto_nft_collection_payload_plugin = require("@xyo-network/crypto-nft-collection-payload-plugin");
|
|
47
46
|
var import_open_zeppelin_typechain3 = require("@xyo-network/open-zeppelin-typechain");
|
|
48
|
-
var
|
|
47
|
+
var import_witness_blockchain_abstract2 = require("@xyo-network/witness-blockchain-abstract");
|
|
49
48
|
|
|
50
49
|
// src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
|
|
51
50
|
var calculateAllPropertiesDistribution = (array) => {
|
|
@@ -124,9 +123,11 @@ var contractHasFunctions = async (provider, address, contractInterface, function
|
|
|
124
123
|
};
|
|
125
124
|
|
|
126
125
|
// src/lib/getNftCollectionNfts.ts
|
|
126
|
+
var import_exists = require("@xylabs/exists");
|
|
127
127
|
var import_axios = require("@xyo-network/axios");
|
|
128
128
|
var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
|
|
129
129
|
var import_open_zeppelin_typechain2 = require("@xyo-network/open-zeppelin-typechain");
|
|
130
|
+
var import_witness_blockchain_abstract = require("@xyo-network/witness-blockchain-abstract");
|
|
130
131
|
|
|
131
132
|
// src/lib/tokenTypes.ts
|
|
132
133
|
var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
|
|
@@ -163,59 +164,52 @@ var tryCall = async (func, name) => {
|
|
|
163
164
|
|
|
164
165
|
// src/lib/getNftCollectionNfts.ts
|
|
165
166
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
let host = url.host;
|
|
170
|
-
let path = url.pathname;
|
|
171
|
-
const query = url.search;
|
|
172
|
-
if (protocol === "ipfs:") {
|
|
173
|
-
protocol = "https:";
|
|
174
|
-
host = ipfsGateway2;
|
|
175
|
-
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
176
|
-
const root = `${protocol}//${host}/${path}`;
|
|
177
|
-
return query?.length > 0 ? `${root}?${query}` : root;
|
|
178
|
-
} else {
|
|
179
|
-
return urlToCheck;
|
|
180
|
-
}
|
|
181
|
-
};
|
|
167
|
+
function range(size, startAt = 0) {
|
|
168
|
+
return [...Array(size).keys()].map((i) => i + startAt);
|
|
169
|
+
}
|
|
182
170
|
var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
|
|
183
171
|
try {
|
|
172
|
+
const { implementation } = await (0, import_witness_blockchain_abstract.getErc1967Status)(provider, contractAddress);
|
|
184
173
|
const axios = new import_axios.AxiosJson({ timeout: 2e3 });
|
|
185
|
-
const enumerable = import_open_zeppelin_typechain2.ERC721Enumerable__factory.connect(
|
|
186
|
-
const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(
|
|
187
|
-
const supply1155 = import_open_zeppelin_typechain2.ERC1155Supply__factory.connect(
|
|
188
|
-
const finalTypes = types ?? await tokenTypes(provider,
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
174
|
+
const enumerable = import_open_zeppelin_typechain2.ERC721Enumerable__factory.connect(implementation, provider);
|
|
175
|
+
const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(implementation, provider);
|
|
176
|
+
const supply1155 = import_open_zeppelin_typechain2.ERC1155Supply__factory.connect(implementation, provider);
|
|
177
|
+
const finalTypes = types ?? await tokenTypes(provider, implementation);
|
|
178
|
+
const maxNftsArray = range(maxNfts);
|
|
179
|
+
const result = (await Promise.all(
|
|
180
|
+
maxNftsArray.map(async (_value, i) => {
|
|
181
|
+
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString()) ?? `${i}`;
|
|
182
|
+
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));
|
|
185
|
+
const checkedMetaDataUri = metadataUri ? (0, import_witness_blockchain_abstract.checkIpfsUrl)(metadataUri, ipfsGateway) : void 0;
|
|
186
|
+
let metadata = void 0;
|
|
187
|
+
if (checkedMetaDataUri !== void 0) {
|
|
188
|
+
try {
|
|
189
|
+
metadata = (await axios.get(checkedMetaDataUri)).data;
|
|
190
|
+
} catch (ex) {
|
|
191
|
+
const error = ex;
|
|
192
|
+
console.error(`Get Metadata failed: ${error.message}`);
|
|
193
|
+
}
|
|
203
194
|
}
|
|
195
|
+
const info = {
|
|
196
|
+
address: contractAddress,
|
|
197
|
+
chainId: provider.network.chainId,
|
|
198
|
+
metadata,
|
|
199
|
+
metadataUri,
|
|
200
|
+
schema: import_crypto_nft_payload_plugin.NftSchema,
|
|
201
|
+
supply,
|
|
202
|
+
tokenId,
|
|
203
|
+
type: finalTypes.at(0),
|
|
204
|
+
types: finalTypes
|
|
205
|
+
};
|
|
206
|
+
if (implementation !== contractAddress) {
|
|
207
|
+
info.implementation = implementation;
|
|
208
|
+
}
|
|
209
|
+
return info;
|
|
204
210
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
chainId: provider.network.chainId,
|
|
208
|
-
metadata,
|
|
209
|
-
metadataUri,
|
|
210
|
-
schema: import_crypto_nft_payload_plugin.NftSchema,
|
|
211
|
-
supply,
|
|
212
|
-
tokenId,
|
|
213
|
-
type: finalTypes.at(0),
|
|
214
|
-
types: finalTypes
|
|
215
|
-
};
|
|
216
|
-
result.push(info);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
211
|
+
})
|
|
212
|
+
)).filter(import_exists.exists);
|
|
219
213
|
return result;
|
|
220
214
|
} catch (ex) {
|
|
221
215
|
const error = ex;
|
|
@@ -238,7 +232,7 @@ var CryptoNftCollectionWitness = class extends import_abstract_witness.AbstractW
|
|
|
238
232
|
static configSchemas = [import_crypto_nft_collection_payload_plugin.NftCollectionWitnessConfigSchema];
|
|
239
233
|
providers = {};
|
|
240
234
|
getProvider(chainId) {
|
|
241
|
-
this.providers[chainId] = this.providers[chainId] ?? (0,
|
|
235
|
+
this.providers[chainId] = this.providers[chainId] ?? (0, import_witness_blockchain_abstract2.getProviderFromEnv)(chainId);
|
|
242
236
|
return this.providers[chainId];
|
|
243
237
|
}
|
|
244
238
|
async observeHandler(payloads) {
|
|
@@ -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 { 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'\n\nimport { tokenTypes } from './tokenTypes'\nimport { tryCall } from './tryCall'\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 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 axios = new AxiosJson({ timeout: 2000 })\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 finalTypes = types ?? (await tokenTypes(provider, contractAddress))\n const result: NftInfo[] = []\n\n for (let i = 0; i < maxNfts; i++) {\n const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString())\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 result.push(info)\n }\n }\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","attributes","p","import_open_zeppelin_typechain","ipfsGateway"]}
|
|
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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,oCAA0B;AAC1B,2BAAiC;AACjC,+BAA8C;;;ACD9C,oBAAyB;AACzB,yBAA2B;AAC3B,8BAAgC;AAChC,kBAA8B;AAC9B,kDAOO;AAEP,IAAAC,kCAA0C;AAC1C,IAAAC,sCAAmC;;;ACb5B,IAAM,qCAAqC,CAAI,UAAgC;AACpF,QAAM,eAAgC,CAAC;AAEvC,QAAM,QAAQ,CAAC,SAAS;AACtB,eAAW,YAAY,MAAM;AAC3B,UAAI,OAAO,UAAU,eAAe,KAAK,MAAM,QAAQ,GAAG;AACxD,cAAM,QAAQ,KAAK,QAAmB;AACtC,YAAI,UAAU,UAAa,UAAU,MAAM;AACzC,gBAAM,cAAc,MAAM,SAAS;AACnC,cAAI,CAAC,aAAa,QAAQ,GAAG;AAC3B,yBAAa,QAAQ,IAAI,EAAE,CAAC,WAAW,GAAG,EAAE;AAAA,UAC9C,WAAW,CAAC,aAAa,QAAQ,EAAG,WAAW,GAAG;AAChD;AAAC,YAAC,aAAa,QAAQ,EAA6B,WAAW,IAAI;AAAA,UACrE,OAAO;AACL;AAAC,YAAC,aAAa,QAAQ,EAA6B,WAAW,KAAK;AAAA,UACtE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;;;AChBO,IAAM,yCAAyC,CAAC,GAAW,MAA8C;AAE9G,QAAM,OAAO,IAAI;AAGjB,QAAM,WAAW,IAAI,KAAK,IAAI;AAG9B,QAAM,SAAS,KAAK,KAAK,QAAQ;AAEjC,SAAO,EAAE,MAAM,GAAG,QAAQ,SAAS;AACrC;;;ACZO,IAAM,0BAA0B,CAAC,SAAgD;AACtF,QAAM,SAAS,KACZ,IAAI,CAAC,QAAQ,KAAK,UAAU,UAA+C,EAC3E,OAAO,CAAC,MAAkC,MAAM,MAAS,EACzD,IAAI,CAACC,gBAAe;AACnB,WAAO,OAAO,YAAYA,YAAW,IAAI,CAAC,cAAc,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,CAAC;AAAA,EAClG,CAAC;AACH,QAAM,eAAe,mCAAmC,MAAM;AAC9D,QAAM,IAAI,KAAK;AACf,QAAM,aAAa,OAAO;AAAA,IACxB,OAAO,QAAQ,YAAY,EACxB,OAAO,CAAC,MAAmC,EAAE,CAAC,MAAM,MAAS,EAC7D,IAAI,CAAC,CAAC,OAAO,OAAO,MAAM;AACzB,YAAM,aAAa,OAAO,OAAO,OAAO,EAAE,OAAO,CAAC,MAAM,SAAS,OAAO,MAAM,CAAC;AAC/E,YAAM,EAAE,EAAE,IAAI,uCAAuC,KAAK,QAAQ,aAAa,CAAC;AAChF,YAAM,SAAS,OAAO;AAAA,QACpB,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,eAAe,MAAM;AACxD,gBAAM,EAAE,GAAAC,GAAE,IAAI,uCAAuC,GAAG,kBAAkB,CAAC;AAC3E,gBAAM,UAA2B,EAAE,UAAU,EAAE,GAAAA,GAAE,GAAG,OAAO,gBAAgB;AAC3E,iBAAO,CAAC,OAAO,OAAO;AAAA,QACxB,CAAC;AAAA,MACH;AACA,aAAO,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,GAAG,OAAO,WAAW,GAAG,OAAO,CAAC;AAAA,IAC5E,CAAC;AAAA,EACL;AACA,SAAO,EAAE,UAAU,EAAE,WAAW,EAAE;AACpC;;;AC9BO,IAAM,uBAAuB,OAAO,UAAoB,SAAiB,mBAA8B,kBAA4B;AACxI,MAAI;AACF,UAAM,WAAW,MAAM,SAAS,QAAQ,SAAS,QAAQ;AACzD,aAAS,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;AAC7C,YAAM,UAAU,kBAAkB,WAAW,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC;AAC1E,UAAI,CAAC,SAAS,SAAS,OAAO,GAAG;AAC/B,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,IAAI;AACX,UAAM,QAAQ;AACd,YAAQ,IAAI,KAAK;AACjB,WAAO;AAAA,EACT;AACF;;;AClBA,oBAAuB;AACvB,mBAA0B;AAC1B,uCAAwE;AACxE,IAAAC,kCAA6F;AAC7F,yCAA+C;;;ACH/C,qCAAqE;AAI9D,IAAM,YAAY,OAAO,UAAoB,YAAoB;AACtE,SAAO,MAAM,qBAAqB,UAAU,SAAS,0DAA2B,gBAAgB,GAAG,CAAC,KAAK,CAAC;AAC5G;AAEO,IAAM,WAAW,OAAO,UAAoB,YAAoB;AACrE,SAAO,MAAM,qBAAqB,UAAU,SAAS,wDAAyB,gBAAgB,GAAG,CAAC,QAAQ,UAAU,UAAU,CAAC;AACjI;AAEO,IAAM,aAAa,OAAO,UAAoB,YAAoB;AACvE,QAAM,CAAC,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI,CAAC,SAAS,UAAU,OAAO,GAAG,UAAU,UAAU,OAAO,CAAC,CAAC;AACvG,QAAM,SAAsB,CAAC;AAC7B,MAAI,QAAQ;AACV,WAAO,KAAK,QAAQ;AAAA,EACtB;AACA,MAAI,SAAS;AACX,WAAO,KAAK,SAAS;AAAA,EACvB;AACA,SAAO;AACT;;;ACxBO,IAAM,UAAU,OAAU,MAAwB,SAA0C;AACjG,MAAI;AACF,WAAO,MAAM,KAAK;AAAA,EACpB,SAAS,IAAI;AACX,QAAI,MAAM;AACR,YAAM,QAAQ;AACd,cAAQ,IAAI,mBAAmB,IAAI,MAAM,MAAM,OAAO,EAAE;AAAA,IAC1D;AACA,WAAO;AAAA,EACT;AACF;;;AFAA,IAAM,cAAc;AAEpB,SAAS,MAAM,MAAc,UAAkB,GAA0B;AACvE,SAAO,CAAC,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO;AACvD;AAEO,IAAM,uBAAuB,OAIlC,iBAIA,UACA,OAMA,UAAU,QACa;AACvB,MAAI;AAEF,UAAM,EAAE,eAAe,IAAI,UAAM,qDAAiB,UAAU,eAAe;AAE3E,UAAM,QAAQ,IAAI,uBAAU,EAAE,SAAS,IAAK,CAAC;AAC7C,UAAM,aAAa,0DAA0B,QAAQ,gBAAgB,QAAQ;AAC7E,UAAM,UAAU,0DAA0B,QAAQ,gBAAgB,QAAQ;AAC1E,UAAM,aAAa,uDAAuB,QAAQ,gBAAgB,QAAQ;AAC1E,UAAM,aAAa,SAAU,MAAM,WAAW,UAAU,cAAc;AAEtE,UAAM,eAAe,MAAM,OAAO;AAElC,UAAM,UACJ,MAAM,QAAQ;AAAA,MACZ,aAAa,IAAI,OAAO,QAAQ,MAAM;AACpC,cAAM,UAAW,MAAM,QAAQ,aAAa,MAAM,WAAW,aAAa,CAAC,GAAG,YAAY,CAAC,KAAM,GAAG,CAAC;AACrG,YAAI,YAAY,QAAW;AACzB,gBAAM,SAAS,WAAW,aAAS,8CAAY,SAAS,CAAC,IACpD,MAAM,QAAQ,aAAa,MAAM,WAAW,YAAY,OAAO,GAAG,YAAY,CAAC,KAAM,SACtF;AACJ,gBAAM,cAAc,MAAM,QAAQ,YAAY,MAAM,QAAQ,SAAS,OAAO,CAAC;AAC7E,gBAAM,qBAAqB,kBAAc,iDAAa,aAAa,WAAW,IAAI;AAClF,cAAI,WAAoC;AACxC,cAAI,uBAAuB,QAAW;AACpC,gBAAI;AACF,0BAAY,MAAM,MAAM,IAAI,kBAAkB,GAAG;AAAA,YACnD,SAAS,IAAI;AACX,oBAAM,QAAQ;AACd,sBAAQ,MAAM,wBAAwB,MAAM,OAAO,EAAE;AAAA,YACvD;AAAA,UACF;AAEA,gBAAM,OAAgB;AAAA,YACpB,SAAS;AAAA,YACT,SAAS,SAAS,QAAQ;AAAA,YAC1B;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA,MAAM,WAAW,GAAG,CAAC;AAAA,YACrB,OAAO;AAAA,UACT;AACA,cAAI,mBAAmB,iBAAiB;AACtC,iBAAK,iBAAiB;AAAA,UACxB;AACA,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH,GACA,OAAO,oBAAM;AACf,WAAO;AAAA,EACT,SAAS,IAAI;AACX,UAAM,QAAQ;AACd,YAAQ,MAAM,iCAAiC,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE;AAC7E,YAAQ,IAAI,MAAM,KAAK;AACvB,WAAO,CAAC;AAAA,EACV;AACF;;;ALhEA,IAAM,iBAAiB;AAOvB,IAAM,OAAO,QAAQ,QAAQ;AAI7B,SAAS,cAAiB,SAAkC,QAAkB;AAC5E,MAAI,UAAU,QAAQ,WAAW,YAAY;AAC3C,UAAM,QAAQ;AAAA,EAChB;AACA,SAAO,QAAQ,WAAW,cAAc,QAAQ,QAAQ;AAC1D;AAEO,IAAM,6BAAN,cAA8H,wCAInI;AAAA,EACA,OAAgB,gBAAgB,CAAC,4EAAgC;AAAA,EAEvD,YAAgE,CAAC;AAAA,EAEjE,YAAY,SAAiB;AACrC,SAAK,UAAU,OAAO,IAAI,KAAK,UAAU,OAAO,SAAK,wDAAmB,OAAO;AAC/E,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B;AAAA,EAEA,MAAyB,eAAe,UAAsE;AAC5G,UAAM,KAAK,QAAQ,OAAO;AAC1B,UAAM,UAAU,UAAU,OAAO,uEAA2B,KAAK,CAAC;AAClE,UAAM,eAAe,MAAM,QAAQ;AAAA,MACjC,QAAQ,IAAgC,OAAO,UAAU;AACvD,cAAM,cAAU,wBAAS,OAAO,WAAW,KAAK,OAAO,SAAS,4BAA4B;AAC5F,cAAM,WAAW,KAAK,YAAY,OAAO;AACzC,cAAM,cAAU;AAAA,UACd,8BAAW,UAAM,wBAAS,OAAO,WAAW,KAAK,OAAO,SAAS,4BAA4B,CAAC;AAAA,UAC9F;AAAA,QACF,EAAE,SAAS;AAEX,cAAM,mBAAmB,0DAA0B,QAAQ,SAAS,QAAQ;AAE5E,cAAM,UAAU,OAAO,WAAW;AAClC,cAAM,CAAC,MAAM,QAAQ,OAAO,cAAc,gBAAgB,IAAI,MAAM,QAAQ,WAAW;AAAA,UACrF,MAAM,iBAAiB,KAAK;AAAA,UAC5B,MAAM,iBAAiB,OAAO;AAAA,WAC7B,MAAM,iBAAiB,YAAY,GAAG,SAAS;AAAA,UAChD,MAAM,WAAW,UAAU,OAAO;AAAA,UAClC,MAAM,KAAK,eAAe;AAAA,QAC5B,CAAC;AACD,cAAM,QAAQ,cAAc,cAAc,IAAI;AAC9C,cAAM,OAAO,MAAM,qBAAqB,SAAS,UAAU,OAAO,OAAO;AACzE,cAAM,UAAU,wBAAwB,IAAI;AAC5C,cAAM,YAAY,cAAc,gBAAgB;AAChD,cAAM,CAAC,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA;AAAA,UAElC,QAAQ,IAAI,KAAK,IAAI,CAAC,QAAQ,0BAAc,UAAU,GAAG,CAAC,CAAC;AAAA;AAAA,UAE3D,YAAY,UAAU,OAAO,IAAI,IAAI;AAAA,QACvC,CAAC;AACD,cAAM,UAA6B;AAAA,UACjC;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM,cAAc,MAAM,IAAI;AAAA,UAC9B,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ,cAAc,QAAQ,IAAI;AAAA,UAClC,OAAO,cAAc,OAAO,IAAI;AAAA,UAChC,MAAM,MAAM,GAAG,CAAC;AAAA,UAChB;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,WAAO,aAAa,KAAK;AAAA,EAC3B;AACF;;;ADtGO,IAAM,mCAAmC,UAC9C;AAAA,EACE,EAAE,UAAU,EAAE,CAAC,2CAAS,GAAG,EAAE,GAAG,QAAQ,sCAAiB;AAAA,EACzD;AAAA,IACE,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,2BAA2B,OAAO,MAAM;AAC7D,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ADPF,IAAO,cAAQ;","names":["import_crypto_nft_payload_plugin","import_open_zeppelin_typechain","import_witness_blockchain_abstract","attributes","p","import_open_zeppelin_typechain"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -93,9 +93,11 @@ var contractHasFunctions = async (provider, address, contractInterface, function
|
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
// src/lib/getNftCollectionNfts.ts
|
|
96
|
+
import { exists } from "@xylabs/exists";
|
|
96
97
|
import { AxiosJson } from "@xyo-network/axios";
|
|
97
98
|
import { NftSchema, toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
98
99
|
import { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
100
|
+
import { checkIpfsUrl, getErc1967Status } from "@xyo-network/witness-blockchain-abstract";
|
|
99
101
|
|
|
100
102
|
// src/lib/tokenTypes.ts
|
|
101
103
|
import { ERC1155URIStorage__factory, IERC721Metadata__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
@@ -132,59 +134,52 @@ var tryCall = async (func, name) => {
|
|
|
132
134
|
|
|
133
135
|
// src/lib/getNftCollectionNfts.ts
|
|
134
136
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
let host = url.host;
|
|
139
|
-
let path = url.pathname;
|
|
140
|
-
const query = url.search;
|
|
141
|
-
if (protocol === "ipfs:") {
|
|
142
|
-
protocol = "https:";
|
|
143
|
-
host = ipfsGateway2;
|
|
144
|
-
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
145
|
-
const root = `${protocol}//${host}/${path}`;
|
|
146
|
-
return query?.length > 0 ? `${root}?${query}` : root;
|
|
147
|
-
} else {
|
|
148
|
-
return urlToCheck;
|
|
149
|
-
}
|
|
150
|
-
};
|
|
137
|
+
function range(size, startAt = 0) {
|
|
138
|
+
return [...Array(size).keys()].map((i) => i + startAt);
|
|
139
|
+
}
|
|
151
140
|
var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
|
|
152
141
|
try {
|
|
142
|
+
const { implementation } = await getErc1967Status(provider, contractAddress);
|
|
153
143
|
const axios = new AxiosJson({ timeout: 2e3 });
|
|
154
|
-
const enumerable = ERC721Enumerable__factory.connect(
|
|
155
|
-
const storage = ERC721URIStorage__factory.connect(
|
|
156
|
-
const supply1155 = ERC1155Supply__factory.connect(
|
|
157
|
-
const finalTypes = types ?? await tokenTypes(provider,
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
144
|
+
const enumerable = ERC721Enumerable__factory.connect(implementation, provider);
|
|
145
|
+
const storage = ERC721URIStorage__factory.connect(implementation, provider);
|
|
146
|
+
const supply1155 = ERC1155Supply__factory.connect(implementation, provider);
|
|
147
|
+
const finalTypes = types ?? await tokenTypes(provider, implementation);
|
|
148
|
+
const maxNftsArray = range(maxNfts);
|
|
149
|
+
const result = (await Promise.all(
|
|
150
|
+
maxNftsArray.map(async (_value, i) => {
|
|
151
|
+
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString()) ?? `${i}`;
|
|
152
|
+
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));
|
|
155
|
+
const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : void 0;
|
|
156
|
+
let metadata = void 0;
|
|
157
|
+
if (checkedMetaDataUri !== void 0) {
|
|
158
|
+
try {
|
|
159
|
+
metadata = (await axios.get(checkedMetaDataUri)).data;
|
|
160
|
+
} catch (ex) {
|
|
161
|
+
const error = ex;
|
|
162
|
+
console.error(`Get Metadata failed: ${error.message}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const info = {
|
|
166
|
+
address: contractAddress,
|
|
167
|
+
chainId: provider.network.chainId,
|
|
168
|
+
metadata,
|
|
169
|
+
metadataUri,
|
|
170
|
+
schema: NftSchema,
|
|
171
|
+
supply,
|
|
172
|
+
tokenId,
|
|
173
|
+
type: finalTypes.at(0),
|
|
174
|
+
types: finalTypes
|
|
175
|
+
};
|
|
176
|
+
if (implementation !== contractAddress) {
|
|
177
|
+
info.implementation = implementation;
|
|
172
178
|
}
|
|
179
|
+
return info;
|
|
173
180
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
chainId: provider.network.chainId,
|
|
177
|
-
metadata,
|
|
178
|
-
metadataUri,
|
|
179
|
-
schema: NftSchema,
|
|
180
|
-
supply,
|
|
181
|
-
tokenId,
|
|
182
|
-
type: finalTypes.at(0),
|
|
183
|
-
types: finalTypes
|
|
184
|
-
};
|
|
185
|
-
result.push(info);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
181
|
+
})
|
|
182
|
+
)).filter(exists);
|
|
188
183
|
return result;
|
|
189
184
|
} catch (ex) {
|
|
190
185
|
const error = ex;
|
|
@@ -275,7 +270,6 @@ var src_default = CryptoNftCollectionWitnessPlugin;
|
|
|
275
270
|
export {
|
|
276
271
|
CryptoNftCollectionWitness,
|
|
277
272
|
CryptoNftCollectionWitnessPlugin,
|
|
278
|
-
checkIpfsUrl,
|
|
279
273
|
contractHasFunctions,
|
|
280
274
|
src_default as default,
|
|
281
275
|
getNftCollectionMetrics,
|
|
@@ -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/contractHasFunctions.ts","../../src/lib/getNftCollectionNfts.ts","../../src/lib/tokenTypes.ts","../../src/lib/tryCall.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 { 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 { 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'\n\nimport { tokenTypes } from './tokenTypes'\nimport { tryCall } from './tryCall'\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 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 axios = new AxiosJson({ timeout: 2000 })\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 finalTypes = types ?? (await tokenTypes(provider, contractAddress))\n const result: NftInfo[] = []\n\n for (let i = 0; i < maxNfts; i++) {\n const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString())\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 result.push(info)\n }\n }\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","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","ERC721Enumerable__factory","attributes","p","ipfsGateway","ERC721Enumerable__factory","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/contractHasFunctions.ts","../../src/lib/getNftCollectionNfts.ts","../../src/lib/tokenTypes.ts","../../src/lib/tryCall.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 { 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","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","ERC721Enumerable__factory","attributes","p","ERC721Enumerable__factory","NftSchema"]}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { BaseProvider } from '@ethersproject/providers';
|
|
2
2
|
import { NftInfo, TokenType } from '@xyo-network/crypto-nft-payload-plugin';
|
|
3
|
-
/**
|
|
4
|
-
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
5
|
-
* @param urlToCheck The URL to check
|
|
6
|
-
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
7
|
-
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
8
|
-
*/
|
|
9
|
-
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
10
3
|
export declare const getNftCollectionNfts: (contractAddress: string, provider: BaseProvider, types?: TokenType[], maxNfts?: number) => Promise<NftInfo[]>;
|
|
11
4
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGvD,OAAO,EAAE,OAAO,EAA0B,SAAS,EAAe,MAAM,wCAAwC,CAAA;AAahH,eAAO,MAAM,oBAAoB,oBAId,MAAM,YAIb,YAAY,UACd,SAAS,EAAE,uBAOlB,QAAQ,OAAO,EAAE,CA2DnB,CAAA"}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { BaseProvider } from '@ethersproject/providers';
|
|
2
2
|
import { NftInfo, TokenType } from '@xyo-network/crypto-nft-payload-plugin';
|
|
3
|
-
/**
|
|
4
|
-
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
5
|
-
* @param urlToCheck The URL to check
|
|
6
|
-
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
7
|
-
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
8
|
-
*/
|
|
9
|
-
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
10
3
|
export declare const getNftCollectionNfts: (contractAddress: string, provider: BaseProvider, types?: TokenType[], maxNfts?: number) => Promise<NftInfo[]>;
|
|
11
4
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGvD,OAAO,EAAE,OAAO,EAA0B,SAAS,EAAe,MAAM,wCAAwC,CAAA;AAahH,eAAO,MAAM,oBAAoB,oBAId,MAAM,YAIb,YAAY,UACd,SAAS,EAAE,uBAOlB,QAAQ,OAAO,EAAE,CA2DnB,CAAA"}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { BaseProvider } from '@ethersproject/providers';
|
|
2
2
|
import { NftInfo, TokenType } from '@xyo-network/crypto-nft-payload-plugin';
|
|
3
|
-
/**
|
|
4
|
-
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
5
|
-
* @param urlToCheck The URL to check
|
|
6
|
-
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
7
|
-
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
8
|
-
*/
|
|
9
|
-
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
10
3
|
export declare const getNftCollectionNfts: (contractAddress: string, provider: BaseProvider, types?: TokenType[], maxNfts?: number) => Promise<NftInfo[]>;
|
|
11
4
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAGvD,OAAO,EAAE,OAAO,EAA0B,SAAS,EAAe,MAAM,wCAAwC,CAAA;AAahH,eAAO,MAAM,oBAAoB,oBAId,MAAM,YAIb,YAAY,UACd,SAAS,EAAE,uBAOlB,QAAQ,OAAO,EAAE,CA2DnB,CAAA"}
|