@xyo-network/crypto-nft-collection-witness-plugin 2.78.3 → 2.78.5

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.
Files changed (82) hide show
  1. package/dist/browser/index.cjs +97 -65
  2. package/dist/browser/index.cjs.map +1 -1
  3. package/dist/browser/index.js +98 -66
  4. package/dist/browser/index.js.map +1 -1
  5. package/dist/browser/lib/contractHasFunctions.d.cts +4 -0
  6. package/dist/browser/lib/contractHasFunctions.d.cts.map +1 -0
  7. package/dist/browser/lib/contractHasFunctions.d.mts +4 -0
  8. package/dist/browser/lib/contractHasFunctions.d.mts.map +1 -0
  9. package/dist/browser/lib/contractHasFunctions.d.ts +4 -0
  10. package/dist/browser/lib/contractHasFunctions.d.ts.map +1 -0
  11. package/dist/browser/lib/getNftCollectionNfts.d.cts.map +1 -1
  12. package/dist/browser/lib/getNftCollectionNfts.d.mts.map +1 -1
  13. package/dist/browser/lib/getNftCollectionNfts.d.ts.map +1 -1
  14. package/dist/browser/lib/getProviderFromEnv.d.cts +3 -2
  15. package/dist/browser/lib/getProviderFromEnv.d.cts.map +1 -1
  16. package/dist/browser/lib/getProviderFromEnv.d.mts +3 -2
  17. package/dist/browser/lib/getProviderFromEnv.d.mts.map +1 -1
  18. package/dist/browser/lib/getProviderFromEnv.d.ts +3 -2
  19. package/dist/browser/lib/getProviderFromEnv.d.ts.map +1 -1
  20. package/dist/browser/lib/index.d.cts +1 -0
  21. package/dist/browser/lib/index.d.cts.map +1 -1
  22. package/dist/browser/lib/index.d.mts +1 -0
  23. package/dist/browser/lib/index.d.mts.map +1 -1
  24. package/dist/browser/lib/index.d.ts +1 -0
  25. package/dist/browser/lib/index.d.ts.map +1 -1
  26. package/dist/browser/lib/tokenTypes.d.cts +4 -6
  27. package/dist/browser/lib/tokenTypes.d.cts.map +1 -1
  28. package/dist/browser/lib/tokenTypes.d.mts +4 -6
  29. package/dist/browser/lib/tokenTypes.d.mts.map +1 -1
  30. package/dist/browser/lib/tokenTypes.d.ts +4 -6
  31. package/dist/browser/lib/tokenTypes.d.ts.map +1 -1
  32. package/dist/browser/lib/tryCall.d.cts +2 -0
  33. package/dist/browser/lib/tryCall.d.cts.map +1 -0
  34. package/dist/browser/lib/tryCall.d.mts +2 -0
  35. package/dist/browser/lib/tryCall.d.mts.map +1 -0
  36. package/dist/browser/lib/tryCall.d.ts +2 -0
  37. package/dist/browser/lib/tryCall.d.ts.map +1 -0
  38. package/dist/node/index.js +99 -66
  39. package/dist/node/index.js.map +1 -1
  40. package/dist/node/index.mjs +98 -66
  41. package/dist/node/index.mjs.map +1 -1
  42. package/dist/node/lib/contractHasFunctions.d.cts +4 -0
  43. package/dist/node/lib/contractHasFunctions.d.cts.map +1 -0
  44. package/dist/node/lib/contractHasFunctions.d.mts +4 -0
  45. package/dist/node/lib/contractHasFunctions.d.mts.map +1 -0
  46. package/dist/node/lib/contractHasFunctions.d.ts +4 -0
  47. package/dist/node/lib/contractHasFunctions.d.ts.map +1 -0
  48. package/dist/node/lib/getNftCollectionNfts.d.cts.map +1 -1
  49. package/dist/node/lib/getNftCollectionNfts.d.mts.map +1 -1
  50. package/dist/node/lib/getNftCollectionNfts.d.ts.map +1 -1
  51. package/dist/node/lib/getProviderFromEnv.d.cts +3 -2
  52. package/dist/node/lib/getProviderFromEnv.d.cts.map +1 -1
  53. package/dist/node/lib/getProviderFromEnv.d.mts +3 -2
  54. package/dist/node/lib/getProviderFromEnv.d.mts.map +1 -1
  55. package/dist/node/lib/getProviderFromEnv.d.ts +3 -2
  56. package/dist/node/lib/getProviderFromEnv.d.ts.map +1 -1
  57. package/dist/node/lib/index.d.cts +1 -0
  58. package/dist/node/lib/index.d.cts.map +1 -1
  59. package/dist/node/lib/index.d.mts +1 -0
  60. package/dist/node/lib/index.d.mts.map +1 -1
  61. package/dist/node/lib/index.d.ts +1 -0
  62. package/dist/node/lib/index.d.ts.map +1 -1
  63. package/dist/node/lib/tokenTypes.d.cts +4 -6
  64. package/dist/node/lib/tokenTypes.d.cts.map +1 -1
  65. package/dist/node/lib/tokenTypes.d.mts +4 -6
  66. package/dist/node/lib/tokenTypes.d.mts.map +1 -1
  67. package/dist/node/lib/tokenTypes.d.ts +4 -6
  68. package/dist/node/lib/tokenTypes.d.ts.map +1 -1
  69. package/dist/node/lib/tryCall.d.cts +2 -0
  70. package/dist/node/lib/tryCall.d.cts.map +1 -0
  71. package/dist/node/lib/tryCall.d.mts +2 -0
  72. package/dist/node/lib/tryCall.d.mts.map +1 -0
  73. package/dist/node/lib/tryCall.d.ts +2 -0
  74. package/dist/node/lib/tryCall.d.ts.map +1 -0
  75. package/package.json +14 -14
  76. package/src/Witness.ts +1 -1
  77. package/src/lib/contractHasFunctions.ts +20 -0
  78. package/src/lib/getNftCollectionNfts.ts +44 -35
  79. package/src/lib/getProviderFromEnv.ts +19 -7
  80. package/src/lib/index.ts +1 -0
  81. package/src/lib/tokenTypes.ts +8 -19
  82. package/src/lib/tryCall.ts +11 -0
@@ -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/getNftCollectionNfts.ts","../../src/lib/nonEvaluableContractAddresses.ts","../../src/lib/tokenTypes.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(erc721Enumerable),\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 { 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 { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\nimport { tokenTypes } from './tokenTypes'\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 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 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(enumerable))\n const result: NftInfo[] = []\n\n for (let i = 0; i < maxNfts; i++) {\n console.log(`Getting Token [${i}]`)\n const tokenId = (await enumerable.tokenByIndex(i)).toHexString()\n const supply = finalTypes.includes(toTokenType('ERC1155')) ? (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: provider.network.chainId,\n metadata,\n metadataUri,\n schema: NftSchema,\n supply,\n tokenId,\n type: finalTypes.at(0),\n types,\n }\n result.push(info)\n }\n return result\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 { Contract } from '@ethersproject/contracts'\nimport { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC1155URIStorage__factory, IERC721Metadata__factory } from '@xyo-network/open-zeppelin-typechain'\n\nexport const isErc1155 = async (contract: Contract) => {\n return await hasFunctions(contract, ERC1155URIStorage__factory.createInterface(), ['uri'])\n}\n\nexport const isErc721 = async (contract: Contract) => {\n return await hasFunctions(contract, IERC721Metadata__factory.createInterface(), ['name', 'symbol', 'tokenURI'])\n}\n\nexport const hasFunctions = async (contract: Contract, contractInterface: Interface, functionNames: string[]) => {\n const bytecode = await contract.provider.getCode(contract.address)\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}\n\nexport const tokenTypes = async (contract: Contract) => {\n const [erc721, erc1155] = await Promise.all([isErc721(contract), isErc1155(contract)])\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","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","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/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 +1 @@
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,CAuCnB,CAAA"}
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"}
@@ -1 +1 @@
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,CAuCnB,CAAA"}
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"}
@@ -1 +1 @@
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,CAuCnB,CAAA"}
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"}
@@ -1,3 +1,4 @@
1
- import { InfuraProvider, WebSocketProvider } from '@ethersproject/providers';
2
- export declare const getProviderFromEnv: (chainId?: string | number) => WebSocketProvider | InfuraProvider;
1
+ import { InfuraProvider, JsonRpcProvider, WebSocketProvider } from '@ethersproject/providers';
2
+ export declare const getProviderFromEnvInternal: (chainId?: number) => InfuraProvider;
3
+ export declare const getProviderFromEnv: (chainId?: number) => JsonRpcProvider | WebSocketProvider;
3
4
  //# sourceMappingURL=getProviderFromEnv.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getProviderFromEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/getProviderFromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5E,eAAO,MAAM,kBAAkB,aAAa,MAAM,GAAG,MAAM,uCAc1D,CAAA"}
1
+ {"version":3,"file":"getProviderFromEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/getProviderFromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE7F,eAAO,MAAM,0BAA0B,aAAa,MAAM,mBAkBzD,CAAA;AAID,eAAO,MAAM,kBAAkB,aAAa,MAAM,wCAIjD,CAAA"}
@@ -1,3 +1,4 @@
1
- import { InfuraProvider, WebSocketProvider } from '@ethersproject/providers';
2
- export declare const getProviderFromEnv: (chainId?: string | number) => WebSocketProvider | InfuraProvider;
1
+ import { InfuraProvider, JsonRpcProvider, WebSocketProvider } from '@ethersproject/providers';
2
+ export declare const getProviderFromEnvInternal: (chainId?: number) => InfuraProvider;
3
+ export declare const getProviderFromEnv: (chainId?: number) => JsonRpcProvider | WebSocketProvider;
3
4
  //# sourceMappingURL=getProviderFromEnv.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getProviderFromEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/getProviderFromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5E,eAAO,MAAM,kBAAkB,aAAa,MAAM,GAAG,MAAM,uCAc1D,CAAA"}
1
+ {"version":3,"file":"getProviderFromEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/getProviderFromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE7F,eAAO,MAAM,0BAA0B,aAAa,MAAM,mBAkBzD,CAAA;AAID,eAAO,MAAM,kBAAkB,aAAa,MAAM,wCAIjD,CAAA"}
@@ -1,3 +1,4 @@
1
- import { InfuraProvider, WebSocketProvider } from '@ethersproject/providers';
2
- export declare const getProviderFromEnv: (chainId?: string | number) => WebSocketProvider | InfuraProvider;
1
+ import { InfuraProvider, JsonRpcProvider, WebSocketProvider } from '@ethersproject/providers';
2
+ export declare const getProviderFromEnvInternal: (chainId?: number) => InfuraProvider;
3
+ export declare const getProviderFromEnv: (chainId?: number) => JsonRpcProvider | WebSocketProvider;
3
4
  //# sourceMappingURL=getProviderFromEnv.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getProviderFromEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/getProviderFromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5E,eAAO,MAAM,kBAAkB,aAAa,MAAM,GAAG,MAAM,uCAc1D,CAAA"}
1
+ {"version":3,"file":"getProviderFromEnv.d.ts","sourceRoot":"","sources":["../../../src/lib/getProviderFromEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE7F,eAAO,MAAM,0BAA0B,aAAa,MAAM,mBAkBzD,CAAA;AAID,eAAO,MAAM,kBAAkB,aAAa,MAAM,wCAIjD,CAAA"}
@@ -1,4 +1,5 @@
1
1
  export * from './collectionMetrics';
2
+ export * from './contractHasFunctions';
2
3
  export * from './getNftCollectionNfts';
3
4
  export * from './getProviderFromEnv';
4
5
  export * from './tokenTypes';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA"}
@@ -1,4 +1,5 @@
1
1
  export * from './collectionMetrics';
2
+ export * from './contractHasFunctions';
2
3
  export * from './getNftCollectionNfts';
3
4
  export * from './getProviderFromEnv';
4
5
  export * from './tokenTypes';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA"}
@@ -1,4 +1,5 @@
1
1
  export * from './collectionMetrics';
2
+ export * from './contractHasFunctions';
2
3
  export * from './getNftCollectionNfts';
3
4
  export * from './getProviderFromEnv';
4
5
  export * from './tokenTypes';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA"}
@@ -1,8 +1,6 @@
1
- import { Interface } from '@ethersproject/abi';
2
- import { Contract } from '@ethersproject/contracts';
1
+ import { Provider } from '@ethersproject/providers';
3
2
  import { TokenType } from '@xyo-network/crypto-nft-payload-plugin';
4
- export declare const isErc1155: (contract: Contract) => Promise<boolean>;
5
- export declare const isErc721: (contract: Contract) => Promise<boolean>;
6
- export declare const hasFunctions: (contract: Contract, contractInterface: Interface, functionNames: string[]) => Promise<boolean>;
7
- export declare const tokenTypes: (contract: Contract) => Promise<TokenType[]>;
3
+ export declare const isErc1155: (provider: Provider, address: string) => Promise<boolean>;
4
+ export declare const isErc721: (provider: Provider, address: string) => Promise<boolean>;
5
+ export declare const tokenTypes: (provider: Provider, address: string) => Promise<TokenType[]>;
8
6
  //# sourceMappingURL=tokenTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokenTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/tokenTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAGlE,eAAO,MAAM,SAAS,aAAoB,QAAQ,qBAEjD,CAAA;AAED,eAAO,MAAM,QAAQ,aAAoB,QAAQ,qBAEhD,CAAA;AAED,eAAO,MAAM,YAAY,aAAoB,QAAQ,qBAAqB,SAAS,iBAAiB,MAAM,EAAE,qBAU3G,CAAA;AAED,eAAO,MAAM,UAAU,aAAoB,QAAQ,yBAUlD,CAAA"}
1
+ {"version":3,"file":"tokenTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/tokenTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAKlE,eAAO,MAAM,SAAS,aAAoB,QAAQ,WAAW,MAAM,qBAElE,CAAA;AAED,eAAO,MAAM,QAAQ,aAAoB,QAAQ,WAAW,MAAM,qBAEjE,CAAA;AAED,eAAO,MAAM,UAAU,aAAoB,QAAQ,WAAW,MAAM,yBAUnE,CAAA"}
@@ -1,8 +1,6 @@
1
- import { Interface } from '@ethersproject/abi';
2
- import { Contract } from '@ethersproject/contracts';
1
+ import { Provider } from '@ethersproject/providers';
3
2
  import { TokenType } from '@xyo-network/crypto-nft-payload-plugin';
4
- export declare const isErc1155: (contract: Contract) => Promise<boolean>;
5
- export declare const isErc721: (contract: Contract) => Promise<boolean>;
6
- export declare const hasFunctions: (contract: Contract, contractInterface: Interface, functionNames: string[]) => Promise<boolean>;
7
- export declare const tokenTypes: (contract: Contract) => Promise<TokenType[]>;
3
+ export declare const isErc1155: (provider: Provider, address: string) => Promise<boolean>;
4
+ export declare const isErc721: (provider: Provider, address: string) => Promise<boolean>;
5
+ export declare const tokenTypes: (provider: Provider, address: string) => Promise<TokenType[]>;
8
6
  //# sourceMappingURL=tokenTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokenTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/tokenTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAGlE,eAAO,MAAM,SAAS,aAAoB,QAAQ,qBAEjD,CAAA;AAED,eAAO,MAAM,QAAQ,aAAoB,QAAQ,qBAEhD,CAAA;AAED,eAAO,MAAM,YAAY,aAAoB,QAAQ,qBAAqB,SAAS,iBAAiB,MAAM,EAAE,qBAU3G,CAAA;AAED,eAAO,MAAM,UAAU,aAAoB,QAAQ,yBAUlD,CAAA"}
1
+ {"version":3,"file":"tokenTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/tokenTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAKlE,eAAO,MAAM,SAAS,aAAoB,QAAQ,WAAW,MAAM,qBAElE,CAAA;AAED,eAAO,MAAM,QAAQ,aAAoB,QAAQ,WAAW,MAAM,qBAEjE,CAAA;AAED,eAAO,MAAM,UAAU,aAAoB,QAAQ,WAAW,MAAM,yBAUnE,CAAA"}
@@ -1,8 +1,6 @@
1
- import { Interface } from '@ethersproject/abi';
2
- import { Contract } from '@ethersproject/contracts';
1
+ import { Provider } from '@ethersproject/providers';
3
2
  import { TokenType } from '@xyo-network/crypto-nft-payload-plugin';
4
- export declare const isErc1155: (contract: Contract) => Promise<boolean>;
5
- export declare const isErc721: (contract: Contract) => Promise<boolean>;
6
- export declare const hasFunctions: (contract: Contract, contractInterface: Interface, functionNames: string[]) => Promise<boolean>;
7
- export declare const tokenTypes: (contract: Contract) => Promise<TokenType[]>;
3
+ export declare const isErc1155: (provider: Provider, address: string) => Promise<boolean>;
4
+ export declare const isErc721: (provider: Provider, address: string) => Promise<boolean>;
5
+ export declare const tokenTypes: (provider: Provider, address: string) => Promise<TokenType[]>;
8
6
  //# sourceMappingURL=tokenTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokenTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/tokenTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAGlE,eAAO,MAAM,SAAS,aAAoB,QAAQ,qBAEjD,CAAA;AAED,eAAO,MAAM,QAAQ,aAAoB,QAAQ,qBAEhD,CAAA;AAED,eAAO,MAAM,YAAY,aAAoB,QAAQ,qBAAqB,SAAS,iBAAiB,MAAM,EAAE,qBAU3G,CAAA;AAED,eAAO,MAAM,UAAU,aAAoB,QAAQ,yBAUlD,CAAA"}
1
+ {"version":3,"file":"tokenTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/tokenTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAKlE,eAAO,MAAM,SAAS,aAAoB,QAAQ,WAAW,MAAM,qBAElE,CAAA;AAED,eAAO,MAAM,QAAQ,aAAoB,QAAQ,WAAW,MAAM,qBAEjE,CAAA;AAED,eAAO,MAAM,UAAU,aAAoB,QAAQ,WAAW,MAAM,yBAUnE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const tryCall: <T>(func: () => Promise<T>, name?: string) => Promise<T | undefined>;
2
+ //# sourceMappingURL=tryCall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryCall.d.ts","sourceRoot":"","sources":["../../../src/lib/tryCall.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,qCAA4C,MAAM,2BAUrE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const tryCall: <T>(func: () => Promise<T>, name?: string) => Promise<T | undefined>;
2
+ //# sourceMappingURL=tryCall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryCall.d.ts","sourceRoot":"","sources":["../../../src/lib/tryCall.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,qCAA4C,MAAM,2BAUrE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const tryCall: <T>(func: () => Promise<T>, name?: string) => Promise<T | undefined>;
2
+ //# sourceMappingURL=tryCall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryCall.d.ts","sourceRoot":"","sources":["../../../src/lib/tryCall.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,qCAA4C,MAAM,2BAUrE,CAAA"}
@@ -23,11 +23,12 @@ __export(src_exports, {
23
23
  CryptoNftCollectionWitness: () => CryptoNftCollectionWitness,
24
24
  CryptoNftCollectionWitnessPlugin: () => CryptoNftCollectionWitnessPlugin,
25
25
  checkIpfsUrl: () => checkIpfsUrl,
26
+ contractHasFunctions: () => contractHasFunctions,
26
27
  default: () => src_default,
27
28
  getNftCollectionMetrics: () => getNftCollectionMetrics,
28
29
  getNftCollectionNfts: () => getNftCollectionNfts,
29
30
  getProviderFromEnv: () => getProviderFromEnv,
30
- hasFunctions: () => hasFunctions,
31
+ getProviderFromEnvInternal: () => getProviderFromEnvInternal,
31
32
  isErc1155: () => isErc1155,
32
33
  isErc721: () => isErc721,
33
34
  tokenTypes: () => tokenTypes
@@ -107,38 +108,40 @@ var getNftCollectionMetrics = (nfts) => {
107
108
  return { metadata: { attributes } };
108
109
  };
109
110
 
111
+ // src/lib/contractHasFunctions.ts
112
+ var contractHasFunctions = async (provider, address, contractInterface, functionNames) => {
113
+ try {
114
+ const bytecode = await provider.getCode(address, "latest");
115
+ for (let i = 0; i < functionNames.length; i++) {
116
+ const nameSig = contractInterface.getSighash(functionNames[i]).substring(2);
117
+ if (!bytecode.includes(nameSig)) {
118
+ return false;
119
+ }
120
+ return true;
121
+ }
122
+ return false;
123
+ } catch (ex) {
124
+ const error = ex;
125
+ console.log(error);
126
+ return false;
127
+ }
128
+ };
129
+
110
130
  // src/lib/getNftCollectionNfts.ts
111
131
  var import_axios = require("@xyo-network/axios");
112
132
  var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
113
133
  var import_open_zeppelin_typechain2 = require("@xyo-network/open-zeppelin-typechain");
114
134
 
115
- // src/lib/nonEvaluableContractAddresses.ts
116
- var nonEvaluableContractAddresses = [
117
- // ENS
118
- "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72"
119
- ].map((address) => address.toUpperCase());
120
-
121
135
  // src/lib/tokenTypes.ts
122
136
  var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
123
- var isErc1155 = async (contract) => {
124
- return await hasFunctions(contract, import_open_zeppelin_typechain.ERC1155URIStorage__factory.createInterface(), ["uri"]);
137
+ var isErc1155 = async (provider, address) => {
138
+ return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC1155URIStorage__factory.createInterface(), ["uri"]);
125
139
  };
126
- var isErc721 = async (contract) => {
127
- return await hasFunctions(contract, import_open_zeppelin_typechain.IERC721Metadata__factory.createInterface(), ["name", "symbol", "tokenURI"]);
140
+ var isErc721 = async (provider, address) => {
141
+ return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.IERC721Metadata__factory.createInterface(), ["name", "symbol", "tokenURI"]);
128
142
  };
129
- var hasFunctions = async (contract, contractInterface, functionNames) => {
130
- const bytecode = await contract.provider.getCode(contract.address);
131
- for (let i = 0; i < functionNames.length; i++) {
132
- const nameSig = contractInterface.getSighash(functionNames[i]).substring(2);
133
- if (!bytecode.includes(nameSig)) {
134
- return false;
135
- }
136
- return true;
137
- }
138
- return false;
139
- };
140
- var tokenTypes = async (contract) => {
141
- const [erc721, erc1155] = await Promise.all([isErc721(contract), isErc1155(contract)]);
143
+ var tokenTypes = async (provider, address) => {
144
+ const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)]);
142
145
  const result = [];
143
146
  if (erc721) {
144
147
  result.push("ERC721");
@@ -149,6 +152,19 @@ var tokenTypes = async (contract) => {
149
152
  return result;
150
153
  };
151
154
 
155
+ // src/lib/tryCall.ts
156
+ var tryCall = async (func, name) => {
157
+ try {
158
+ return await func();
159
+ } catch (ex) {
160
+ if (name) {
161
+ const error = ex;
162
+ console.log(`tryCall failed [${name}]: ${error.message}`);
163
+ }
164
+ return void 0;
165
+ }
166
+ };
167
+
152
168
  // src/lib/getNftCollectionNfts.ts
153
169
  var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
154
170
  var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
@@ -168,58 +184,74 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
168
184
  }
169
185
  };
170
186
  var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
171
- if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
172
- throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
173
- }
174
- const axios = new import_axios.AxiosJson({ timeout: 2e3 });
175
- const enumerable = import_open_zeppelin_typechain2.ERC721Enumerable__factory.connect(contractAddress, provider);
176
- const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(contractAddress, provider);
177
- const supply1155 = import_open_zeppelin_typechain2.ERC1155Supply__factory.connect(contractAddress, provider);
178
- const finalTypes = types ?? await tokenTypes(enumerable);
179
- const result = [];
180
- for (let i = 0; i < maxNfts; i++) {
181
- console.log(`Getting Token [${i}]`);
182
- const tokenId = (await enumerable.tokenByIndex(i)).toHexString();
183
- const supply = finalTypes.includes((0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155")) ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
184
- const metadataUri = await storage.tokenURI(tokenId);
185
- const checkedMetaDataUri = checkIpfsUrl(metadataUri, ipfsGateway);
186
- let metadata = void 0;
187
- try {
188
- metadata = (await axios.get(checkedMetaDataUri)).data;
189
- } catch (ex) {
190
- const error = ex;
191
- console.error(error.message);
187
+ try {
188
+ const axios = new import_axios.AxiosJson({ timeout: 2e3 });
189
+ const enumerable = import_open_zeppelin_typechain2.ERC721Enumerable__factory.connect(contractAddress, provider);
190
+ const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(contractAddress, provider);
191
+ const supply1155 = import_open_zeppelin_typechain2.ERC1155Supply__factory.connect(contractAddress, provider);
192
+ const finalTypes = types ?? await tokenTypes(provider, contractAddress);
193
+ const result = [];
194
+ for (let i = 0; i < maxNfts; i++) {
195
+ const tokenId = await tryCall(async () => (await enumerable.tokenByIndex(i)).toHexString());
196
+ if (tokenId !== void 0) {
197
+ const supply = finalTypes.includes((0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155")) ? await tryCall(async () => (await supply1155.totalSupply(tokenId)).toHexString()) ?? "0x01" : "0x01";
198
+ const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId));
199
+ const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : void 0;
200
+ let metadata = void 0;
201
+ if (checkedMetaDataUri !== void 0) {
202
+ try {
203
+ metadata = (await axios.get(checkedMetaDataUri)).data;
204
+ } catch (ex) {
205
+ const error = ex;
206
+ console.error(`Get Metadata failed: ${error.message}`);
207
+ }
208
+ }
209
+ const info = {
210
+ address: contractAddress,
211
+ chainId: provider.network.chainId,
212
+ metadata,
213
+ metadataUri,
214
+ schema: import_crypto_nft_payload_plugin.NftSchema,
215
+ supply,
216
+ tokenId,
217
+ type: finalTypes.at(0),
218
+ types: finalTypes
219
+ };
220
+ result.push(info);
221
+ }
192
222
  }
193
- const info = {
194
- address: contractAddress,
195
- chainId: provider.network.chainId,
196
- metadata,
197
- metadataUri,
198
- schema: import_crypto_nft_payload_plugin.NftSchema,
199
- supply,
200
- tokenId,
201
- type: finalTypes.at(0),
202
- types
203
- };
204
- result.push(info);
223
+ return result;
224
+ } catch (ex) {
225
+ const error = ex;
226
+ console.error(`getNftCollectionNfts failed: [${error.name}] ${error.message}`);
227
+ console.log(error.stack);
228
+ return [];
205
229
  }
206
- return result;
207
230
  };
208
231
 
209
232
  // src/lib/getProviderFromEnv.ts
210
233
  var import_providers = require("@ethersproject/providers");
211
- var getProviderFromEnv = (chainId = "homestead") => {
234
+ var getProviderFromEnvInternal = (chainId = 1) => {
235
+ console.log(`getProviderFromEnvInternal: ${chainId}`);
212
236
  const infuraWssUri = process.env.INFURA_WSS_URI;
213
- const infuraProvider = new import_providers.InfuraProvider("homestead", {
237
+ const infuraProvider = new import_providers.InfuraProvider(chainId, {
214
238
  projectId: process.env.INFURA_PROJECT_ID,
215
239
  projectSecret: process.env.INFURA_PROJECT_SECRET
216
240
  });
217
- const infuraWebsocketProvider = infuraWssUri ? new import_providers.WebSocketProvider(infuraWssUri, chainId) : void 0;
218
- const quickNodeUri = process.env.QUICKNODE_WSS_URI;
219
- const quickNodeProvider = quickNodeUri ? new import_providers.WebSocketProvider(quickNodeUri, chainId) : void 0;
220
- const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
241
+ const infuraGenericWebsocketProvider = infuraWssUri ? new import_providers.WebSocketProvider(infuraWssUri, chainId) : void 0;
242
+ const quickNodeWSSUri = process.env.QUICKNODE_WSS_URI;
243
+ const quickNodeWebSocketProvider = quickNodeWSSUri ? new import_providers.WebSocketProvider(quickNodeWSSUri, chainId) : void 0;
244
+ const quickNodeHttpsUri = process.env.QUICKNODE_WSS_URI;
245
+ const quickRpcProvider = quickNodeHttpsUri ? new import_providers.JsonRpcProvider(quickNodeHttpsUri, chainId) : void 0;
246
+ const provider = infuraProvider ?? quickNodeWebSocketProvider ?? infuraProvider ?? infuraGenericWebsocketProvider ?? quickRpcProvider;
221
247
  return provider;
222
248
  };
249
+ var providers = {};
250
+ var getProviderFromEnv = (chainId = 1) => {
251
+ console.log(`getProviderFromEnv: ${chainId}`);
252
+ providers[chainId] = providers[chainId] ?? getProviderFromEnvInternal(chainId);
253
+ return providers[chainId];
254
+ };
223
255
 
224
256
  // src/Witness.ts
225
257
  var defaultMaxNfts = 100;
@@ -254,7 +286,7 @@ var CryptoNftCollectionWitness = class extends import_abstract_witness.AbstractW
254
286
  await erc721Enumerable.name(),
255
287
  await erc721Enumerable.symbol(),
256
288
  (await erc721Enumerable.totalSupply()).toNumber(),
257
- await tokenTypes(erc721Enumerable),
289
+ await tokenTypes(provider, address),
258
290
  await this.writeArchivist()
259
291
  ]);
260
292
  const types = resolvedValue(typesSettled, true);
@@ -304,10 +336,11 @@ var src_default = CryptoNftCollectionWitnessPlugin;
304
336
  CryptoNftCollectionWitness,
305
337
  CryptoNftCollectionWitnessPlugin,
306
338
  checkIpfsUrl,
339
+ contractHasFunctions,
307
340
  getNftCollectionMetrics,
308
341
  getNftCollectionNfts,
309
342
  getProviderFromEnv,
310
- hasFunctions,
343
+ getProviderFromEnvInternal,
311
344
  isErc1155,
312
345
  isErc721,
313
346
  tokenTypes