@xyo-network/crypto-nft-collection-witness-plugin 2.78.2 → 2.78.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/Plugin.d.cts +2 -0
- package/dist/browser/Plugin.d.cts.map +1 -1
- package/dist/browser/Plugin.d.mts +2 -0
- package/dist/browser/Plugin.d.mts.map +1 -1
- package/dist/browser/Plugin.d.ts +2 -0
- package/dist/browser/Plugin.d.ts.map +1 -1
- package/dist/browser/Witness.d.cts +6 -1
- package/dist/browser/Witness.d.cts.map +1 -1
- package/dist/browser/Witness.d.mts +6 -1
- package/dist/browser/Witness.d.mts.map +1 -1
- package/dist/browser/Witness.d.ts +6 -1
- package/dist/browser/Witness.d.ts.map +1 -1
- package/dist/browser/index.cjs +155 -114
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +155 -114
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lib/contractHasFunctions.d.cts +4 -0
- package/dist/browser/lib/contractHasFunctions.d.cts.map +1 -0
- package/dist/browser/lib/contractHasFunctions.d.mts +4 -0
- package/dist/browser/lib/contractHasFunctions.d.mts.map +1 -0
- package/dist/browser/lib/contractHasFunctions.d.ts +4 -0
- package/dist/browser/lib/contractHasFunctions.d.ts.map +1 -0
- package/dist/browser/lib/getNftCollectionNfts.d.cts +3 -2
- package/dist/browser/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.mts +3 -2
- package/dist/browser/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/browser/lib/getNftCollectionNfts.d.ts +3 -2
- package/dist/browser/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/dist/browser/lib/getProviderFromEnv.d.cts +4 -0
- package/dist/browser/lib/getProviderFromEnv.d.cts.map +1 -0
- package/dist/browser/lib/getProviderFromEnv.d.mts +4 -0
- package/dist/browser/lib/getProviderFromEnv.d.mts.map +1 -0
- package/dist/browser/lib/getProviderFromEnv.d.ts +4 -0
- package/dist/browser/lib/getProviderFromEnv.d.ts.map +1 -0
- package/dist/browser/lib/index.d.cts +3 -2
- package/dist/browser/lib/index.d.cts.map +1 -1
- package/dist/browser/lib/index.d.mts +3 -2
- package/dist/browser/lib/index.d.mts.map +1 -1
- package/dist/browser/lib/index.d.ts +3 -2
- package/dist/browser/lib/index.d.ts.map +1 -1
- package/dist/browser/lib/tokenTypes.d.cts +6 -0
- package/dist/browser/lib/tokenTypes.d.cts.map +1 -0
- package/dist/browser/lib/tokenTypes.d.mts +6 -0
- package/dist/browser/lib/tokenTypes.d.mts.map +1 -0
- package/dist/browser/lib/tokenTypes.d.ts +6 -0
- package/dist/browser/lib/tokenTypes.d.ts.map +1 -0
- package/dist/browser/lib/tryCall.d.cts +2 -0
- package/dist/browser/lib/tryCall.d.cts.map +1 -0
- package/dist/browser/lib/tryCall.d.mts +2 -0
- package/dist/browser/lib/tryCall.d.mts.map +1 -0
- package/dist/browser/lib/tryCall.d.ts +2 -0
- package/dist/browser/lib/tryCall.d.ts.map +1 -0
- package/dist/node/Plugin.d.cts +2 -0
- package/dist/node/Plugin.d.cts.map +1 -1
- package/dist/node/Plugin.d.mts +2 -0
- package/dist/node/Plugin.d.mts.map +1 -1
- package/dist/node/Plugin.d.ts +2 -0
- package/dist/node/Plugin.d.ts.map +1 -1
- package/dist/node/Witness.d.cts +6 -1
- package/dist/node/Witness.d.cts.map +1 -1
- package/dist/node/Witness.d.mts +6 -1
- package/dist/node/Witness.d.mts.map +1 -1
- package/dist/node/Witness.d.ts +6 -1
- package/dist/node/Witness.d.ts.map +1 -1
- package/dist/node/index.js +162 -118
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +155 -114
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/lib/contractHasFunctions.d.cts +4 -0
- package/dist/node/lib/contractHasFunctions.d.cts.map +1 -0
- package/dist/node/lib/contractHasFunctions.d.mts +4 -0
- package/dist/node/lib/contractHasFunctions.d.mts.map +1 -0
- package/dist/node/lib/contractHasFunctions.d.ts +4 -0
- package/dist/node/lib/contractHasFunctions.d.ts.map +1 -0
- package/dist/node/lib/getNftCollectionNfts.d.cts +3 -2
- package/dist/node/lib/getNftCollectionNfts.d.cts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.mts +3 -2
- package/dist/node/lib/getNftCollectionNfts.d.mts.map +1 -1
- package/dist/node/lib/getNftCollectionNfts.d.ts +3 -2
- package/dist/node/lib/getNftCollectionNfts.d.ts.map +1 -1
- package/dist/node/lib/getProviderFromEnv.d.cts +4 -0
- package/dist/node/lib/getProviderFromEnv.d.cts.map +1 -0
- package/dist/node/lib/getProviderFromEnv.d.mts +4 -0
- package/dist/node/lib/getProviderFromEnv.d.mts.map +1 -0
- package/dist/node/lib/getProviderFromEnv.d.ts +4 -0
- package/dist/node/lib/getProviderFromEnv.d.ts.map +1 -0
- package/dist/node/lib/index.d.cts +3 -2
- package/dist/node/lib/index.d.cts.map +1 -1
- package/dist/node/lib/index.d.mts +3 -2
- package/dist/node/lib/index.d.mts.map +1 -1
- package/dist/node/lib/index.d.ts +3 -2
- package/dist/node/lib/index.d.ts.map +1 -1
- package/dist/node/lib/tokenTypes.d.cts +6 -0
- package/dist/node/lib/tokenTypes.d.cts.map +1 -0
- package/dist/node/lib/tokenTypes.d.mts +6 -0
- package/dist/node/lib/tokenTypes.d.mts.map +1 -0
- package/dist/node/lib/tokenTypes.d.ts +6 -0
- package/dist/node/lib/tokenTypes.d.ts.map +1 -0
- package/dist/node/lib/tryCall.d.cts +2 -0
- package/dist/node/lib/tryCall.d.cts.map +1 -0
- package/dist/node/lib/tryCall.d.mts +2 -0
- package/dist/node/lib/tryCall.d.mts.map +1 -0
- package/dist/node/lib/tryCall.d.ts +2 -0
- package/dist/node/lib/tryCall.d.ts.map +1 -0
- package/package.json +17 -13
- package/src/Witness.ts +51 -9
- package/src/lib/contractHasFunctions.ts +20 -0
- package/src/lib/getNftCollectionNfts.ts +49 -38
- package/src/lib/getProviderFromEnv.ts +29 -0
- package/src/lib/index.ts +3 -2
- package/src/lib/tokenTypes.ts +25 -0
- package/src/lib/tryCall.ts +11 -0
- package/dist/browser/lib/getNftCollectionCount.d.cts +0 -2
- package/dist/browser/lib/getNftCollectionCount.d.cts.map +0 -1
- package/dist/browser/lib/getNftCollectionCount.d.mts +0 -2
- package/dist/browser/lib/getNftCollectionCount.d.mts.map +0 -1
- package/dist/browser/lib/getNftCollectionCount.d.ts +0 -2
- package/dist/browser/lib/getNftCollectionCount.d.ts.map +0 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.cts +0 -5
- package/dist/browser/lib/getNftCollectionMetadata.d.cts.map +0 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.mts +0 -5
- package/dist/browser/lib/getNftCollectionMetadata.d.mts.map +0 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.ts +0 -5
- package/dist/browser/lib/getNftCollectionMetadata.d.ts.map +0 -1
- package/dist/browser/lib/getProvider.d.cts +0 -3
- package/dist/browser/lib/getProvider.d.cts.map +0 -1
- package/dist/browser/lib/getProvider.d.mts +0 -3
- package/dist/browser/lib/getProvider.d.mts.map +0 -1
- package/dist/browser/lib/getProvider.d.ts +0 -3
- package/dist/browser/lib/getProvider.d.ts.map +0 -1
- package/dist/node/lib/getNftCollectionCount.d.cts +0 -2
- package/dist/node/lib/getNftCollectionCount.d.cts.map +0 -1
- package/dist/node/lib/getNftCollectionCount.d.mts +0 -2
- package/dist/node/lib/getNftCollectionCount.d.mts.map +0 -1
- package/dist/node/lib/getNftCollectionCount.d.ts +0 -2
- package/dist/node/lib/getNftCollectionCount.d.ts.map +0 -1
- package/dist/node/lib/getNftCollectionMetadata.d.cts +0 -5
- package/dist/node/lib/getNftCollectionMetadata.d.cts.map +0 -1
- package/dist/node/lib/getNftCollectionMetadata.d.mts +0 -5
- package/dist/node/lib/getNftCollectionMetadata.d.mts.map +0 -1
- package/dist/node/lib/getNftCollectionMetadata.d.ts +0 -5
- package/dist/node/lib/getNftCollectionMetadata.d.ts.map +0 -1
- package/dist/node/lib/getProvider.d.cts +0 -3
- package/dist/node/lib/getProvider.d.cts.map +0 -1
- package/dist/node/lib/getProvider.d.mts +0 -3
- package/dist/node/lib/getProvider.d.mts.map +0 -1
- package/dist/node/lib/getProvider.d.ts +0 -3
- package/dist/node/lib/getProvider.d.ts.map +0 -1
- package/src/lib/getNftCollectionCount.ts +0 -22
- package/src/lib/getNftCollectionMetadata.ts +0 -58
- package/src/lib/getProvider.ts +0 -17
package/dist/node/index.js.map
CHANGED
|
@@ -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/getNftCollectionCount.ts","../../src/lib/getProvider.ts","../../src/lib/nonEvaluableContractAddresses.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getNftCollectionNfts.ts"],"sourcesContent":["import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness'\n\nexport const CryptoNftCollectionWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoNftCollectionWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoNftCollectionWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { 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"],"mappings":"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","names":["import_crypto_nft_payload_plugin","attributes","p","import_open_zeppelin_typechain","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","../../src/lib/getProviderFromEnv.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 { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftCollectionMetrics, getNftCollectionNfts, getProviderFromEnv, 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 { JsonRpcProvider } 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: JsonRpcProvider,\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 { InfuraProvider, JsonRpcProvider, WebSocketProvider } from '@ethersproject/providers'\n\nexport const getProviderFromEnvInternal = (chainId: number = 0x01) => {\n console.log(`getProviderFromEnvInternal: ${chainId}`)\n const infuraWssUri = process.env.INFURA_WSS_URI\n const infuraProvider = new InfuraProvider(chainId, {\n projectId: process.env.INFURA_PROJECT_ID,\n projectSecret: process.env.INFURA_PROJECT_SECRET,\n })\n\n const infuraGenericWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : undefined\n\n const quickNodeWSSUri = process.env.QUICKNODE_WSS_URI\n const quickNodeWebSocketProvider = quickNodeWSSUri ? new WebSocketProvider(quickNodeWSSUri, chainId) : undefined\n\n const quickNodeHttpsUri = process.env.QUICKNODE_WSS_URI\n const quickRpcProvider = quickNodeHttpsUri ? new JsonRpcProvider(quickNodeHttpsUri, chainId) : undefined\n\n const provider = infuraProvider ?? quickNodeWebSocketProvider ?? infuraProvider ?? infuraGenericWebsocketProvider ?? quickRpcProvider\n return provider\n}\n\nconst providers: Record<number, JsonRpcProvider | WebSocketProvider> = {}\n\nexport const getProviderFromEnv = (chainId: number = 0x01) => {\n console.log(`getProviderFromEnv: ${chainId}`)\n providers[chainId] = providers[chainId] ?? getProviderFromEnvInternal(chainId)\n return providers[chainId]\n}\n"],"mappings":"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","names":["import_crypto_nft_payload_plugin","import_open_zeppelin_typechain","attributes","p","import_open_zeppelin_typechain","ipfsGateway"]}
|
package/dist/node/index.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
NftCollectionSchema,
|
|
14
14
|
NftCollectionWitnessConfigSchema
|
|
15
15
|
} from "@xyo-network/crypto-nft-collection-payload-plugin";
|
|
16
|
+
import { ERC721Enumerable__factory as ERC721Enumerable__factory2 } from "@xyo-network/open-zeppelin-typechain";
|
|
16
17
|
|
|
17
18
|
// src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
|
|
18
19
|
var calculateAllPropertiesDistribution = (array) => {
|
|
@@ -74,87 +75,64 @@ var getNftCollectionMetrics = (nfts) => {
|
|
|
74
75
|
return { metadata: { attributes } };
|
|
75
76
|
};
|
|
76
77
|
|
|
77
|
-
// src/lib/
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
// src/lib/contractHasFunctions.ts
|
|
79
|
+
var contractHasFunctions = async (provider, address, contractInterface, functionNames) => {
|
|
80
|
+
try {
|
|
81
|
+
const bytecode = await provider.getCode(address, "latest");
|
|
82
|
+
for (let i = 0; i < functionNames.length; i++) {
|
|
83
|
+
const nameSig = contractInterface.getSighash(functionNames[i]).substring(2);
|
|
84
|
+
if (!bytecode.includes(nameSig)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
} catch (ex) {
|
|
91
|
+
const error = ex;
|
|
92
|
+
console.log(error);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
93
95
|
};
|
|
94
96
|
|
|
95
|
-
// src/lib/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
].map((address) => address.toUpperCase());
|
|
97
|
+
// src/lib/getNftCollectionNfts.ts
|
|
98
|
+
import { AxiosJson } from "@xyo-network/axios";
|
|
99
|
+
import { NftSchema, toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
100
|
+
import { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
100
101
|
|
|
101
|
-
// src/lib/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
const provider = getProviderFromEnv(chainId);
|
|
107
|
-
const contract = ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
108
|
-
return (await contract.totalSupply()).toNumber();
|
|
102
|
+
// src/lib/tokenTypes.ts
|
|
103
|
+
import { ERC1155URIStorage__factory, IERC721Metadata__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
104
|
+
var isErc1155 = async (provider, address) => {
|
|
105
|
+
return await contractHasFunctions(provider, address, ERC1155URIStorage__factory.createInterface(), ["uri"]);
|
|
109
106
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
|
|
119
|
-
}
|
|
120
|
-
return interfaceID.toHexString();
|
|
121
|
-
}
|
|
122
|
-
var getNftCollectionMetadata = async (contractAddress, chainId) => {
|
|
123
|
-
if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
|
|
124
|
-
throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
|
|
125
|
-
}
|
|
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}`);
|
|
107
|
+
var isErc721 = async (provider, address) => {
|
|
108
|
+
return await contractHasFunctions(provider, address, IERC721Metadata__factory.createInterface(), ["name", "symbol", "tokenURI"]);
|
|
109
|
+
};
|
|
110
|
+
var tokenTypes = async (provider, address) => {
|
|
111
|
+
const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)]);
|
|
112
|
+
const result = [];
|
|
113
|
+
if (erc721) {
|
|
114
|
+
result.push("ERC721");
|
|
135
115
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
symbol = await contract721.symbol();
|
|
139
|
-
} catch (ex) {
|
|
140
|
-
const error = ex;
|
|
141
|
-
console.log(`symbol: ${error.message}`);
|
|
116
|
+
if (erc1155) {
|
|
117
|
+
result.push("ERC1155");
|
|
142
118
|
}
|
|
143
|
-
|
|
119
|
+
return result;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// src/lib/tryCall.ts
|
|
123
|
+
var tryCall = async (func, name) => {
|
|
144
124
|
try {
|
|
145
|
-
|
|
125
|
+
return await func();
|
|
146
126
|
} catch (ex) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
127
|
+
if (name) {
|
|
128
|
+
const error = ex;
|
|
129
|
+
console.log(`tryCall failed [${name}]: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
return void 0;
|
|
150
132
|
}
|
|
151
|
-
return { address: contractAddress, chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
|
|
152
133
|
};
|
|
153
134
|
|
|
154
135
|
// src/lib/getNftCollectionNfts.ts
|
|
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
136
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
159
137
|
var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
160
138
|
const url = new URL(urlToCheck);
|
|
@@ -172,74 +150,134 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
|
172
150
|
return urlToCheck;
|
|
173
151
|
}
|
|
174
152
|
};
|
|
175
|
-
var getNftCollectionNfts = async (contractAddress,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
153
|
+
var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
|
|
154
|
+
try {
|
|
155
|
+
const axios = new AxiosJson({ timeout: 2e3 });
|
|
156
|
+
const enumerable = ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
157
|
+
const storage = ERC721URIStorage__factory.connect(contractAddress, provider);
|
|
158
|
+
const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider);
|
|
159
|
+
const finalTypes = types ?? await tokenTypes(provider, contractAddress);
|
|
160
|
+
const result = [];
|
|
161
|
+
for (let i = 0; i < maxNfts; i++) {
|
|
162
|
+
const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString());
|
|
163
|
+
if (tokenId !== void 0) {
|
|
164
|
+
const supply = finalTypes.includes(toTokenType("ERC1155")) ? await tryCall(async () => (await supply1155.totalSupply(tokenId)).toHexString()) ?? "0x01" : "0x01";
|
|
165
|
+
const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId));
|
|
166
|
+
const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : void 0;
|
|
167
|
+
let metadata = void 0;
|
|
168
|
+
if (checkedMetaDataUri !== void 0) {
|
|
169
|
+
try {
|
|
170
|
+
metadata = (await axios.get(checkedMetaDataUri)).data;
|
|
171
|
+
} catch (ex) {
|
|
172
|
+
const error = ex;
|
|
173
|
+
console.error(`Get Metadata failed: ${error.message}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const info = {
|
|
177
|
+
address: contractAddress,
|
|
178
|
+
chainId: provider.network.chainId,
|
|
179
|
+
metadata,
|
|
180
|
+
metadataUri,
|
|
181
|
+
schema: NftSchema,
|
|
182
|
+
supply,
|
|
183
|
+
tokenId,
|
|
184
|
+
type: finalTypes.at(0),
|
|
185
|
+
types: finalTypes
|
|
186
|
+
};
|
|
187
|
+
result.push(info);
|
|
188
|
+
}
|
|
197
189
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
supply,
|
|
205
|
-
tokenId,
|
|
206
|
-
type: nftType
|
|
207
|
-
};
|
|
208
|
-
result.push(info);
|
|
190
|
+
return result;
|
|
191
|
+
} catch (ex) {
|
|
192
|
+
const error = ex;
|
|
193
|
+
console.error(`getNftCollectionNfts failed: [${error.name}] ${error.message}`);
|
|
194
|
+
console.log(error.stack);
|
|
195
|
+
return [];
|
|
209
196
|
}
|
|
210
|
-
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// src/lib/getProviderFromEnv.ts
|
|
200
|
+
import { InfuraProvider, JsonRpcProvider, WebSocketProvider } from "@ethersproject/providers";
|
|
201
|
+
var getProviderFromEnvInternal = (chainId = 1) => {
|
|
202
|
+
console.log(`getProviderFromEnvInternal: ${chainId}`);
|
|
203
|
+
const infuraWssUri = process.env.INFURA_WSS_URI;
|
|
204
|
+
const infuraProvider = new InfuraProvider(chainId, {
|
|
205
|
+
projectId: process.env.INFURA_PROJECT_ID,
|
|
206
|
+
projectSecret: process.env.INFURA_PROJECT_SECRET
|
|
207
|
+
});
|
|
208
|
+
const infuraGenericWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : void 0;
|
|
209
|
+
const quickNodeWSSUri = process.env.QUICKNODE_WSS_URI;
|
|
210
|
+
const quickNodeWebSocketProvider = quickNodeWSSUri ? new WebSocketProvider(quickNodeWSSUri, chainId) : void 0;
|
|
211
|
+
const quickNodeHttpsUri = process.env.QUICKNODE_WSS_URI;
|
|
212
|
+
const quickRpcProvider = quickNodeHttpsUri ? new JsonRpcProvider(quickNodeHttpsUri, chainId) : void 0;
|
|
213
|
+
const provider = infuraProvider ?? quickNodeWebSocketProvider ?? infuraProvider ?? infuraGenericWebsocketProvider ?? quickRpcProvider;
|
|
214
|
+
return provider;
|
|
215
|
+
};
|
|
216
|
+
var providers = {};
|
|
217
|
+
var getProviderFromEnv = (chainId = 1) => {
|
|
218
|
+
console.log(`getProviderFromEnv: ${chainId}`);
|
|
219
|
+
providers[chainId] = providers[chainId] ?? getProviderFromEnvInternal(chainId);
|
|
220
|
+
return providers[chainId];
|
|
211
221
|
};
|
|
212
222
|
|
|
213
223
|
// src/Witness.ts
|
|
214
224
|
var defaultMaxNfts = 100;
|
|
215
225
|
var NoOp = Promise.resolve();
|
|
226
|
+
function resolvedValue(settled, assert) {
|
|
227
|
+
if (assert && settled.status === "rejected") {
|
|
228
|
+
throw settled.reason;
|
|
229
|
+
}
|
|
230
|
+
return settled.status === "fulfilled" ? settled.value : void 0;
|
|
231
|
+
}
|
|
216
232
|
var CryptoNftCollectionWitness = class extends AbstractWitness {
|
|
217
233
|
static configSchemas = [NftCollectionWitnessConfigSchema];
|
|
234
|
+
providers = {};
|
|
235
|
+
getProvider(chainId) {
|
|
236
|
+
this.providers[chainId] = this.providers[chainId] ?? getProviderFromEnv(chainId);
|
|
237
|
+
return this.providers[chainId];
|
|
238
|
+
}
|
|
218
239
|
async observeHandler(payloads) {
|
|
219
240
|
await this.started("throw");
|
|
220
241
|
const queries = (payloads == null ? void 0 : payloads.filter(isNftCollectionWitnessQuery)) ?? [];
|
|
221
242
|
const observations = await Promise.all(
|
|
222
243
|
queries.map(async (query) => {
|
|
244
|
+
const chainId = assertEx((query == null ? void 0 : query.chainId) || this.config.chainId, "params.chainId is required");
|
|
245
|
+
const provider = this.getProvider(chainId);
|
|
223
246
|
const address = assertEx(
|
|
224
247
|
EthAddress.parse(assertEx((query == null ? void 0 : query.address) || this.config.address, "params.address is required")),
|
|
225
248
|
"Failed to parse params.address"
|
|
226
249
|
).toString();
|
|
227
|
-
const
|
|
250
|
+
const erc721Enumerable = ERC721Enumerable__factory2.connect(address, provider);
|
|
228
251
|
const maxNfts = (query == null ? void 0 : query.maxNfts) || defaultMaxNfts;
|
|
229
|
-
const [
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
252
|
+
const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([
|
|
253
|
+
await erc721Enumerable.name(),
|
|
254
|
+
await erc721Enumerable.symbol(),
|
|
255
|
+
(await erc721Enumerable.totalSupply()).toNumber(),
|
|
256
|
+
await tokenTypes(provider, address),
|
|
257
|
+
await this.writeArchivist()
|
|
234
258
|
]);
|
|
259
|
+
const types = resolvedValue(typesSettled, true);
|
|
260
|
+
const nfts = await getNftCollectionNfts(address, provider, types, maxNfts);
|
|
235
261
|
const metrics = getNftCollectionMetrics(nfts);
|
|
262
|
+
const archivist = resolvedValue(archivistSettled);
|
|
236
263
|
const [sources] = await Promise.all([
|
|
237
264
|
// Hash all the payloads
|
|
238
265
|
Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),
|
|
239
266
|
// Insert them into the archivist if we have one
|
|
240
267
|
archivist ? archivist.insert(nfts) : NoOp
|
|
241
268
|
]);
|
|
242
|
-
const payload = {
|
|
269
|
+
const payload = {
|
|
270
|
+
address,
|
|
271
|
+
chainId,
|
|
272
|
+
metrics,
|
|
273
|
+
name: resolvedValue(name, true),
|
|
274
|
+
schema: NftCollectionSchema,
|
|
275
|
+
sources,
|
|
276
|
+
symbol: resolvedValue(symbol, true),
|
|
277
|
+
total: resolvedValue(total, true),
|
|
278
|
+
type: types.at(0),
|
|
279
|
+
types
|
|
280
|
+
};
|
|
243
281
|
return payload;
|
|
244
282
|
})
|
|
245
283
|
);
|
|
@@ -264,11 +302,14 @@ export {
|
|
|
264
302
|
CryptoNftCollectionWitness,
|
|
265
303
|
CryptoNftCollectionWitnessPlugin,
|
|
266
304
|
checkIpfsUrl,
|
|
305
|
+
contractHasFunctions,
|
|
267
306
|
src_default as default,
|
|
268
|
-
getInterfaceID,
|
|
269
|
-
getNftCollectionCount,
|
|
270
|
-
getNftCollectionMetadata,
|
|
271
307
|
getNftCollectionMetrics,
|
|
272
|
-
getNftCollectionNfts
|
|
308
|
+
getNftCollectionNfts,
|
|
309
|
+
getProviderFromEnv,
|
|
310
|
+
getProviderFromEnvInternal,
|
|
311
|
+
isErc1155,
|
|
312
|
+
isErc721,
|
|
313
|
+
tokenTypes
|
|
273
314
|
};
|
|
274
315
|
//# sourceMappingURL=index.mjs.map
|
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/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
|
+
{"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/lib/getProviderFromEnv.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 { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftCollectionMetrics, getNftCollectionNfts, getProviderFromEnv, 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 { JsonRpcProvider } 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: JsonRpcProvider,\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 { InfuraProvider, JsonRpcProvider, WebSocketProvider } from '@ethersproject/providers'\n\nexport const getProviderFromEnvInternal = (chainId: number = 0x01) => {\n console.log(`getProviderFromEnvInternal: ${chainId}`)\n const infuraWssUri = process.env.INFURA_WSS_URI\n const infuraProvider = new InfuraProvider(chainId, {\n projectId: process.env.INFURA_PROJECT_ID,\n projectSecret: process.env.INFURA_PROJECT_SECRET,\n })\n\n const infuraGenericWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : undefined\n\n const quickNodeWSSUri = process.env.QUICKNODE_WSS_URI\n const quickNodeWebSocketProvider = quickNodeWSSUri ? new WebSocketProvider(quickNodeWSSUri, chainId) : undefined\n\n const quickNodeHttpsUri = process.env.QUICKNODE_WSS_URI\n const quickRpcProvider = quickNodeHttpsUri ? new JsonRpcProvider(quickNodeHttpsUri, chainId) : undefined\n\n const provider = infuraProvider ?? quickNodeWebSocketProvider ?? infuraProvider ?? infuraGenericWebsocketProvider ?? quickRpcProvider\n return provider\n}\n\nconst providers: Record<number, JsonRpcProvider | WebSocketProvider> = {}\n\nexport const getProviderFromEnv = (chainId: number = 0x01) => {\n console.log(`getProviderFromEnv: ${chainId}`)\n providers[chainId] = providers[chainId] ?? getProviderFromEnvInternal(chainId)\n return providers[chainId]\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"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { Provider } from '@ethersproject/providers';
|
|
3
|
+
export declare const contractHasFunctions: (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => Promise<boolean>;
|
|
4
|
+
//# sourceMappingURL=contractHasFunctions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractHasFunctions.d.ts","sourceRoot":"","sources":["../../../src/lib/contractHasFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,eAAO,MAAM,oBAAoB,aAAoB,QAAQ,WAAW,MAAM,qBAAqB,SAAS,iBAAiB,MAAM,EAAE,qBAgBpI,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { Provider } from '@ethersproject/providers';
|
|
3
|
+
export declare const contractHasFunctions: (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => Promise<boolean>;
|
|
4
|
+
//# sourceMappingURL=contractHasFunctions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractHasFunctions.d.ts","sourceRoot":"","sources":["../../../src/lib/contractHasFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,eAAO,MAAM,oBAAoB,aAAoB,QAAQ,WAAW,MAAM,qBAAqB,SAAS,iBAAiB,MAAM,EAAE,qBAgBpI,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { Provider } from '@ethersproject/providers';
|
|
3
|
+
export declare const contractHasFunctions: (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => Promise<boolean>;
|
|
4
|
+
//# sourceMappingURL=contractHasFunctions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contractHasFunctions.d.ts","sourceRoot":"","sources":["../../../src/lib/contractHasFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,eAAO,MAAM,oBAAoB,aAAoB,QAAQ,WAAW,MAAM,qBAAqB,SAAS,iBAAiB,MAAM,EAAE,qBAgBpI,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JsonRpcProvider } from '@ethersproject/providers';
|
|
2
|
+
import { NftInfo, TokenType } from '@xyo-network/crypto-nft-payload-plugin';
|
|
2
3
|
/**
|
|
3
4
|
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
4
5
|
* @param urlToCheck The URL to check
|
|
@@ -6,5 +7,5 @@ import { NftInfo } from '@xyo-network/crypto-nft-payload-plugin';
|
|
|
6
7
|
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
7
8
|
*/
|
|
8
9
|
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway: string) => string;
|
|
9
|
-
export declare const getNftCollectionNfts: (contractAddress: string,
|
|
10
|
+
export declare const getNftCollectionNfts: (contractAddress: string, provider: JsonRpcProvider, types?: TokenType[], maxNfts?: number) => Promise<NftInfo[]>;
|
|
10
11
|
//# sourceMappingURL=getNftCollectionNfts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,EAAE,OAAO,EAA0B,SAAS,EAAe,MAAM,wCAAwC,CAAA;AAQhH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,eAAe,MAAM,WAenE,CAAA;AAED,eAAO,MAAM,oBAAoB,oBAId,MAAM,YAIb,eAAe,UACjB,SAAS,EAAE,uBAOlB,QAAQ,OAAO,EAAE,CAgDnB,CAAA"}
|