@xyo-network/crypto-nft-collection-witness-plugin 2.99.3 → 2.99.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 (123) hide show
  1. package/dist/browser/Plugin.d.cts +1 -1
  2. package/dist/browser/Plugin.d.mts +1 -1
  3. package/dist/browser/Plugin.d.ts +1 -1
  4. package/dist/browser/index.cjs +175 -127
  5. package/dist/browser/index.cjs.map +1 -1
  6. package/dist/browser/index.d.cts +3 -3
  7. package/dist/browser/index.d.mts +3 -3
  8. package/dist/browser/index.d.ts +3 -3
  9. package/dist/browser/index.mjs +325 -0
  10. package/dist/browser/index.mjs.map +1 -0
  11. package/dist/browser/lib/collectionMetrics/index.d.cts +1 -1
  12. package/dist/browser/lib/collectionMetrics/index.d.mts +1 -1
  13. package/dist/browser/lib/collectionMetrics/index.d.ts +1 -1
  14. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts +1 -1
  15. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.mts +1 -1
  16. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.ts +1 -1
  17. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts +1 -1
  18. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.d.mts +1 -1
  19. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.d.ts +1 -1
  20. package/dist/browser/lib/collectionMetrics/lib/index.d.cts +3 -3
  21. package/dist/browser/lib/collectionMetrics/lib/index.d.mts +3 -3
  22. package/dist/browser/lib/collectionMetrics/lib/index.d.ts +3 -3
  23. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts +2 -2
  24. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.mts +2 -2
  25. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.ts +2 -2
  26. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts +1 -1
  27. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.d.mts +1 -1
  28. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.d.ts +1 -1
  29. package/dist/browser/lib/index.d.cts +4 -4
  30. package/dist/browser/lib/index.d.mts +4 -4
  31. package/dist/browser/lib/index.d.ts +4 -4
  32. package/dist/browser/lib/nonEvaluableContractAddresses.d.cts.map +1 -1
  33. package/dist/browser/lib/nonEvaluableContractAddresses.d.mts.map +1 -1
  34. package/dist/browser/lib/nonEvaluableContractAddresses.d.ts.map +1 -1
  35. package/dist/neutral/Plugin.d.cts +1 -1
  36. package/dist/neutral/Plugin.d.mts +1 -1
  37. package/dist/neutral/Plugin.d.ts +1 -1
  38. package/dist/neutral/index.cjs +175 -127
  39. package/dist/neutral/index.cjs.map +1 -1
  40. package/dist/neutral/index.d.cts +3 -3
  41. package/dist/neutral/index.d.mts +3 -3
  42. package/dist/neutral/index.d.ts +3 -3
  43. package/dist/neutral/index.mjs +325 -0
  44. package/dist/neutral/index.mjs.map +1 -0
  45. package/dist/neutral/lib/collectionMetrics/index.d.cts +1 -1
  46. package/dist/neutral/lib/collectionMetrics/index.d.mts +1 -1
  47. package/dist/neutral/lib/collectionMetrics/index.d.ts +1 -1
  48. package/dist/neutral/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts +1 -1
  49. package/dist/neutral/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.mts +1 -1
  50. package/dist/neutral/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.ts +1 -1
  51. package/dist/neutral/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts +1 -1
  52. package/dist/neutral/lib/collectionMetrics/lib/calculatePropertyDistribution.d.mts +1 -1
  53. package/dist/neutral/lib/collectionMetrics/lib/calculatePropertyDistribution.d.ts +1 -1
  54. package/dist/neutral/lib/collectionMetrics/lib/index.d.cts +3 -3
  55. package/dist/neutral/lib/collectionMetrics/lib/index.d.mts +3 -3
  56. package/dist/neutral/lib/collectionMetrics/lib/index.d.ts +3 -3
  57. package/dist/neutral/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts +2 -2
  58. package/dist/neutral/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.mts +2 -2
  59. package/dist/neutral/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.ts +2 -2
  60. package/dist/neutral/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts +1 -1
  61. package/dist/neutral/lib/collectionMetrics/lib/probabilityDistributions/index.d.mts +1 -1
  62. package/dist/neutral/lib/collectionMetrics/lib/probabilityDistributions/index.d.ts +1 -1
  63. package/dist/neutral/lib/index.d.cts +4 -4
  64. package/dist/neutral/lib/index.d.mts +4 -4
  65. package/dist/neutral/lib/index.d.ts +4 -4
  66. package/dist/neutral/lib/nonEvaluableContractAddresses.d.cts.map +1 -1
  67. package/dist/neutral/lib/nonEvaluableContractAddresses.d.mts.map +1 -1
  68. package/dist/neutral/lib/nonEvaluableContractAddresses.d.ts.map +1 -1
  69. package/dist/node/Plugin.d.cts +1 -1
  70. package/dist/node/Plugin.d.mts +1 -1
  71. package/dist/node/Plugin.d.ts +1 -1
  72. package/dist/node/index.cjs +181 -129
  73. package/dist/node/index.cjs.map +1 -1
  74. package/dist/node/index.d.cts +3 -3
  75. package/dist/node/index.d.mts +3 -3
  76. package/dist/node/index.d.ts +3 -3
  77. package/dist/node/index.mjs +333 -0
  78. package/dist/node/index.mjs.map +1 -0
  79. package/dist/node/lib/collectionMetrics/index.d.cts +1 -1
  80. package/dist/node/lib/collectionMetrics/index.d.mts +1 -1
  81. package/dist/node/lib/collectionMetrics/index.d.ts +1 -1
  82. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts +1 -1
  83. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.mts +1 -1
  84. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.ts +1 -1
  85. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts +1 -1
  86. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.d.mts +1 -1
  87. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.d.ts +1 -1
  88. package/dist/node/lib/collectionMetrics/lib/index.d.cts +3 -3
  89. package/dist/node/lib/collectionMetrics/lib/index.d.mts +3 -3
  90. package/dist/node/lib/collectionMetrics/lib/index.d.ts +3 -3
  91. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts +2 -2
  92. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.mts +2 -2
  93. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.ts +2 -2
  94. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts +1 -1
  95. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.d.mts +1 -1
  96. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.d.ts +1 -1
  97. package/dist/node/lib/index.d.cts +4 -4
  98. package/dist/node/lib/index.d.mts +4 -4
  99. package/dist/node/lib/index.d.ts +4 -4
  100. package/dist/node/lib/nonEvaluableContractAddresses.d.cts.map +1 -1
  101. package/dist/node/lib/nonEvaluableContractAddresses.d.mts.map +1 -1
  102. package/dist/node/lib/nonEvaluableContractAddresses.d.ts.map +1 -1
  103. package/package.json +25 -25
  104. package/src/Plugin.ts +1 -1
  105. package/src/Witness.ts +3 -3
  106. package/src/index.ts +3 -3
  107. package/src/lib/collectionMetrics/getNftCollectionMetrics.ts +3 -3
  108. package/src/lib/collectionMetrics/index.ts +1 -1
  109. package/src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts +1 -1
  110. package/src/lib/collectionMetrics/lib/calculatePropertyDistribution.ts +1 -1
  111. package/src/lib/collectionMetrics/lib/index.ts +3 -3
  112. package/src/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.ts +2 -2
  113. package/src/lib/collectionMetrics/lib/probabilityDistributions/index.ts +1 -1
  114. package/src/lib/getNftCollectionNfts.ts +13 -13
  115. package/src/lib/index.ts +4 -4
  116. package/src/lib/nonEvaluableContractAddresses.ts +1 -1
  117. package/src/lib/tokenTypes.ts +1 -1
  118. package/dist/browser/index.js +0 -279
  119. package/dist/browser/index.js.map +0 -1
  120. package/dist/neutral/index.js +0 -279
  121. package/dist/neutral/index.js.map +0 -1
  122. package/dist/node/index.js +0 -283
  123. package/dist/node/index.js.map +0 -1
@@ -1,4 +1,4 @@
1
1
  import { PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin';
2
- import { CryptoNftCollectionWitness } from './Witness.js';
2
+ import { CryptoNftCollectionWitness } from './Witness.ts';
3
3
  export declare const CryptoNftCollectionWitnessPlugin: () => PayloadSetWitnessPlugin<CryptoNftCollectionWitness>;
4
4
  //# sourceMappingURL=Plugin.d.ts.map
@@ -1,4 +1,4 @@
1
1
  import { PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin';
2
- import { CryptoNftCollectionWitness } from './Witness.js';
2
+ import { CryptoNftCollectionWitness } from './Witness.ts';
3
3
  export declare const CryptoNftCollectionWitnessPlugin: () => PayloadSetWitnessPlugin<CryptoNftCollectionWitness>;
4
4
  //# sourceMappingURL=Plugin.d.ts.map
@@ -1,4 +1,4 @@
1
1
  import { PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin';
2
- import { CryptoNftCollectionWitness } from './Witness.js';
2
+ import { CryptoNftCollectionWitness } from './Witness.ts';
3
3
  export declare const CryptoNftCollectionWitnessPlugin: () => PayloadSetWitnessPlugin<CryptoNftCollectionWitness>;
4
4
  //# sourceMappingURL=Plugin.d.ts.map
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -33,7 +34,7 @@ __export(src_exports, {
33
34
  module.exports = __toCommonJS(src_exports);
34
35
 
35
36
  // src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
36
- var calculateAllPropertiesDistribution = (array) => {
37
+ var calculateAllPropertiesDistribution = /* @__PURE__ */ __name((array) => {
37
38
  const distribution = {};
38
39
  for (const item of array) {
39
40
  for (const property in item) {
@@ -42,12 +43,12 @@ var calculateAllPropertiesDistribution = (array) => {
42
43
  if (value !== void 0 && value !== null) {
43
44
  const valueString = value.toString();
44
45
  if (!distribution[property]) {
45
- distribution[property] = { [valueString]: 1 };
46
+ distribution[property] = {
47
+ [valueString]: 1
48
+ };
46
49
  } else if (distribution[property][valueString]) {
47
- ;
48
50
  distribution[property][valueString] += 1;
49
51
  } else {
50
- ;
51
52
  distribution[property][valueString] = 1;
52
53
  }
53
54
  }
@@ -55,43 +56,70 @@ var calculateAllPropertiesDistribution = (array) => {
55
56
  }
56
57
  }
57
58
  return distribution;
58
- };
59
+ }, "calculateAllPropertiesDistribution");
59
60
 
60
61
  // src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts
61
- var calculateBinomialParamsFromProbability = (n, p) => {
62
+ var calculateBinomialParamsFromProbability = /* @__PURE__ */ __name((n, p) => {
62
63
  const mean = n * p;
63
64
  const variance = n * p * (1 - p);
64
65
  const stdDev = Math.sqrt(variance);
65
- return { mean, p, stdDev, variance };
66
- };
66
+ return {
67
+ mean,
68
+ p,
69
+ stdDev,
70
+ variance
71
+ };
72
+ }, "calculateBinomialParamsFromProbability");
67
73
 
68
74
  // src/lib/collectionMetrics/getNftCollectionMetrics.ts
69
- var getNftCollectionMetrics = (nfts) => {
75
+ var getNftCollectionMetrics = /* @__PURE__ */ __name((nfts) => {
70
76
  const traits = nfts.map((nft) => nft?.metadata?.attributes).filter((v) => v !== void 0).map((attributes2) => {
71
- return Object.fromEntries(attributes2.map((attribute) => [attribute.trait_type, attribute.value]));
77
+ return Object.fromEntries(attributes2.map((attribute) => [
78
+ attribute.trait_type,
79
+ attribute.value
80
+ ]));
72
81
  });
73
82
  const distribution = calculateAllPropertiesDistribution(traits);
74
83
  const n = nfts.length;
75
- const attributes = Object.fromEntries(
76
- Object.entries(distribution).filter((v) => v[1] !== void 0).map(([trait, entries]) => {
77
- const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0);
78
- const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n);
79
- const values = Object.fromEntries(
80
- Object.entries(entries).map(([value, traitValueCount]) => {
81
- const { p: p2 } = calculateBinomialParamsFromProbability(n, traitValueCount / n);
82
- const metrics = { binomial: { p: p2 }, count: traitValueCount };
83
- return [value, metrics];
84
- })
85
- );
86
- return [trait, { metrics: { binomial: { p }, count: traitCount }, values }];
87
- })
88
- );
89
- return { metadata: { attributes } };
90
- };
84
+ const attributes = Object.fromEntries(Object.entries(distribution).filter((v) => v[1] !== void 0).map(([trait, entries]) => {
85
+ const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0);
86
+ const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n);
87
+ const values = Object.fromEntries(Object.entries(entries).map(([value, traitValueCount]) => {
88
+ const { p: p2 } = calculateBinomialParamsFromProbability(n, traitValueCount / n);
89
+ const metrics = {
90
+ binomial: {
91
+ p: p2
92
+ },
93
+ count: traitValueCount
94
+ };
95
+ return [
96
+ value,
97
+ metrics
98
+ ];
99
+ }));
100
+ return [
101
+ trait,
102
+ {
103
+ metrics: {
104
+ binomial: {
105
+ p
106
+ },
107
+ count: traitCount
108
+ },
109
+ values
110
+ }
111
+ ];
112
+ }));
113
+ return {
114
+ metadata: {
115
+ attributes
116
+ }
117
+ };
118
+ }, "getNftCollectionMetrics");
91
119
 
92
120
  // src/lib/contractHasFunctions.ts
93
121
  var import_assert = require("@xylabs/assert");
94
- var contractHasFunctions = async (provider, address, contractInterface, functionNames) => {
122
+ var contractHasFunctions = /* @__PURE__ */ __name(async (provider, address, contractInterface, functionNames) => {
95
123
  try {
96
124
  const bytecode = await provider.getCode(address, "latest");
97
125
  for (const functionName of functionNames) {
@@ -107,7 +135,7 @@ var contractHasFunctions = async (provider, address, contractInterface, function
107
135
  console.log(error);
108
136
  return false;
109
137
  }
110
- };
138
+ }, "contractHasFunctions");
111
139
 
112
140
  // src/lib/getNftCollectionNfts.ts
113
141
  var import_axios = require("@xylabs/axios");
@@ -121,14 +149,23 @@ var import_witness_blockchain_abstract = require("@xyo-network/witness-blockchai
121
149
 
122
150
  // src/lib/tokenTypes.ts
123
151
  var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
124
- var isErc1155 = async (provider, address) => {
125
- return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC1155URIStorage__factory.createInterface(), ["uri"]);
126
- };
127
- var isErc721 = async (provider, address) => {
128
- return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC721__factory.createInterface(), ["name", "symbol", "tokenURI"]);
129
- };
130
- var tokenTypes = async (provider, address) => {
131
- const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)]);
152
+ var isErc1155 = /* @__PURE__ */ __name(async (provider, address) => {
153
+ return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC1155URIStorage__factory.createInterface(), [
154
+ "uri"
155
+ ]);
156
+ }, "isErc1155");
157
+ var isErc721 = /* @__PURE__ */ __name(async (provider, address) => {
158
+ return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC721__factory.createInterface(), [
159
+ "name",
160
+ "symbol",
161
+ "tokenURI"
162
+ ]);
163
+ }, "isErc721");
164
+ var tokenTypes = /* @__PURE__ */ __name(async (provider, address) => {
165
+ const [erc721, erc1155] = await Promise.all([
166
+ isErc721(provider, address),
167
+ isErc1155(provider, address)
168
+ ]);
132
169
  const result = [];
133
170
  if (erc721) {
134
171
  result.push("ERC721");
@@ -137,10 +174,10 @@ var tokenTypes = async (provider, address) => {
137
174
  result.push("ERC1155");
138
175
  }
139
176
  return result;
140
- };
177
+ }, "tokenTypes");
141
178
 
142
179
  // src/lib/tryCall.ts
143
- var tryCall = async (func, name) => {
180
+ var tryCall = /* @__PURE__ */ __name(async (func, name) => {
144
181
  try {
145
182
  return await func();
146
183
  } catch (ex) {
@@ -150,59 +187,66 @@ var tryCall = async (func, name) => {
150
187
  }
151
188
  return void 0;
152
189
  }
153
- };
190
+ }, "tryCall");
154
191
 
155
192
  // src/lib/getNftCollectionNfts.ts
156
193
  var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
157
194
  function range(size, startAt = 0) {
158
- return [...Array(size).keys()].map((i) => i + startAt);
195
+ return [
196
+ ...Array(size).keys()
197
+ ].map((i) => i + startAt);
159
198
  }
160
- var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 100) => {
199
+ __name(range, "range");
200
+ var getNftCollectionNfts = /* @__PURE__ */ __name(async (contractAddress, provider, types, maxNfts = 100) => {
161
201
  try {
162
202
  const block = await provider.getBlockNumber();
163
203
  const erc1967Status = await (0, import_erc1967_witness.getErc1967SlotStatus)(provider, contractAddress, block);
164
204
  const erc1822Status = await (0, import_erc1822_witness.getErc1822SlotStatus)(provider, contractAddress, block);
165
205
  const implementation = !erc1967Status.slots.implementation || (0, import_hex.isHexZero)(erc1967Status.slots.implementation) ? erc1822Status.implementation : erc1967Status.implementation;
166
- const axios = new import_axios.AxiosJson({ timeout: 2e3 });
206
+ const axios = new import_axios.AxiosJson({
207
+ timeout: 2e3
208
+ });
167
209
  const enumerable = import_open_zeppelin_typechain2.ERC721Enumerable__factory.connect(implementation, provider);
168
210
  const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(implementation, provider);
169
211
  const supply1155 = import_open_zeppelin_typechain2.ERC1155Supply__factory.connect(implementation, provider);
170
212
  const finalTypes = types ?? await tokenTypes(provider, implementation);
171
213
  const maxNftsArray = range(maxNfts);
172
- const result = (await Promise.all(
173
- maxNftsArray.map(async (_value, i) => {
174
- const tokenId = await tryCall(async () => await enumerable.tokenByIndex(i, { blockTag: block })) ?? BigInt(i);
175
- if (tokenId !== void 0) {
176
- const supply = finalTypes.includes((0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155")) ? await tryCall(async () => await supply1155["totalSupply(uint256)"](tokenId)) ?? "0x01" : "0x01";
177
- const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, { blockTag: block }));
178
- const checkedMetaDataUri = metadataUri ? (0, import_witness_blockchain_abstract.checkIpfsUrl)(metadataUri, ipfsGateway) : void 0;
179
- let metadata;
180
- if (checkedMetaDataUri !== void 0) {
181
- try {
182
- metadata = (await axios.get(checkedMetaDataUri)).data;
183
- } catch (ex) {
184
- const error = ex;
185
- console.error(`Get Metadata failed: ${error.message}`);
186
- }
214
+ const result = (await Promise.all(maxNftsArray.map(async (_value, i) => {
215
+ const tokenId = await tryCall(async () => await enumerable.tokenByIndex(i, {
216
+ blockTag: block
217
+ })) ?? BigInt(i);
218
+ if (tokenId !== void 0) {
219
+ const supply = finalTypes.includes((0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155")) ? await tryCall(async () => await supply1155["totalSupply(uint256)"](tokenId)) ?? "0x01" : "0x01";
220
+ const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, {
221
+ blockTag: block
222
+ }));
223
+ const checkedMetaDataUri = metadataUri ? (0, import_witness_blockchain_abstract.checkIpfsUrl)(metadataUri, ipfsGateway) : void 0;
224
+ let metadata;
225
+ if (checkedMetaDataUri !== void 0) {
226
+ try {
227
+ metadata = (await axios.get(checkedMetaDataUri)).data;
228
+ } catch (ex) {
229
+ const error = ex;
230
+ console.error(`Get Metadata failed: ${error.message}`);
187
231
  }
188
- const info = {
189
- address: contractAddress,
190
- chainId: Number((await provider.getNetwork()).chainId),
191
- metadata,
192
- metadataUri,
193
- schema: import_crypto_nft_payload_plugin.NftSchema,
194
- supply: `0x${supply.toString(16)}`,
195
- tokenId: `0x${tokenId.toString(16)}`,
196
- type: finalTypes.at(0),
197
- types: finalTypes
198
- };
199
- if (implementation !== contractAddress) {
200
- info.implementation = implementation;
201
- }
202
- return info;
203
232
  }
204
- })
205
- )).filter(import_exists.exists);
233
+ const info = {
234
+ address: contractAddress,
235
+ chainId: Number((await provider.getNetwork()).chainId),
236
+ metadata,
237
+ metadataUri,
238
+ schema: import_crypto_nft_payload_plugin.NftSchema,
239
+ supply: `0x${supply.toString(16)}`,
240
+ tokenId: `0x${tokenId.toString(16)}`,
241
+ type: finalTypes.at(0),
242
+ types: finalTypes
243
+ };
244
+ if (implementation !== contractAddress) {
245
+ info.implementation = implementation;
246
+ }
247
+ return info;
248
+ }
249
+ }))).filter(import_exists.exists);
206
250
  return result;
207
251
  } catch (ex) {
208
252
  const error = ex;
@@ -210,7 +254,7 @@ var getNftCollectionNfts = async (contractAddress, provider, types, maxNfts = 10
210
254
  console.log(error.stack);
211
255
  return [];
212
256
  }
213
- };
257
+ }, "getNftCollectionNfts");
214
258
 
215
259
  // src/Plugin.ts
216
260
  var import_crypto_nft_payload_plugin2 = require("@xyo-network/crypto-nft-payload-plugin");
@@ -232,67 +276,71 @@ function resolvedValue(settled, assert) {
232
276
  }
233
277
  return settled.status === "fulfilled" ? settled.value : void 0;
234
278
  }
279
+ __name(resolvedValue, "resolvedValue");
235
280
  var CryptoNftCollectionWitness = class extends import_witness_evm_abstract.AbstractEvmWitness {
236
- static configSchemas = [...super.configSchemas, import_crypto_nft_collection_payload_plugin.NftCollectionWitnessConfigSchema];
281
+ static {
282
+ __name(this, "CryptoNftCollectionWitness");
283
+ }
284
+ static configSchemas = [
285
+ ...super.configSchemas,
286
+ import_crypto_nft_collection_payload_plugin.NftCollectionWitnessConfigSchema
287
+ ];
237
288
  static defaultConfigSchema = import_crypto_nft_collection_payload_plugin.NftCollectionWitnessConfigSchema;
238
289
  async observeHandler(payloads) {
239
290
  await this.started("throw");
240
291
  await this.getProviders();
241
292
  const queries = payloads?.filter(import_crypto_nft_collection_payload_plugin.isNftCollectionWitnessQuery) ?? [];
242
- const observations = await Promise.all(
243
- queries.map(async (query) => {
244
- const chainId = (0, import_assert2.assertEx)(query?.chainId || this.config.chainId, () => "params.chainId is required");
245
- const provider = await this.getProvider(true, true);
246
- const address = (0, import_assert2.assertEx)(
247
- import_eth_address.EthAddress.parse((0, import_assert2.assertEx)(query?.address || this.config.address, () => "params.address is required")),
248
- () => "Failed to parse params.address"
249
- ).toString();
250
- const erc721Enumerable = import_open_zeppelin_typechain3.ERC721Enumerable__factory.connect(address, provider);
251
- const maxNfts = query?.maxNfts || defaultMaxNfts;
252
- const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([
253
- erc721Enumerable.name(),
254
- erc721Enumerable.symbol(),
255
- erc721Enumerable.totalSupply(),
256
- tokenTypes(provider, address),
257
- this.archivistInstance()
258
- ]);
259
- const types = resolvedValue(typesSettled, true);
260
- const nfts = await getNftCollectionNfts(address, provider, types, maxNfts);
261
- const metrics = getNftCollectionMetrics(nfts);
262
- const archivist = resolvedValue(archivistSettled);
263
- const [sources] = await Promise.all([
264
- // Hash all the payloads
265
- Promise.all(nfts.map((nft) => import_payload_builder.PayloadBuilder.dataHash(nft))),
266
- // Insert them into the archivist if we have one
267
- archivist ? archivist.insert(nfts) : NoOp
268
- ]);
269
- const payload = {
270
- address,
271
- chainId,
272
- metrics,
273
- name: resolvedValue(name, true),
274
- schema: import_crypto_nft_collection_payload_plugin.NftCollectionSchema,
275
- sources,
276
- symbol: resolvedValue(symbol, true),
277
- total: Number(resolvedValue(total, true)),
278
- type: types.at(0),
279
- types
280
- };
281
- return payload;
282
- })
283
- );
293
+ const observations = await Promise.all(queries.map(async (query) => {
294
+ const chainId = (0, import_assert2.assertEx)(query?.chainId || this.config.chainId, () => "params.chainId is required");
295
+ const provider = await this.getProvider(true, true);
296
+ const address = (0, import_assert2.assertEx)(import_eth_address.EthAddress.parse((0, import_assert2.assertEx)(query?.address || this.config.address, () => "params.address is required")), () => "Failed to parse params.address").toString();
297
+ const erc721Enumerable = import_open_zeppelin_typechain3.ERC721Enumerable__factory.connect(address, provider);
298
+ const maxNfts = query?.maxNfts || defaultMaxNfts;
299
+ const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([
300
+ erc721Enumerable.name(),
301
+ erc721Enumerable.symbol(),
302
+ erc721Enumerable.totalSupply(),
303
+ tokenTypes(provider, address),
304
+ this.archivistInstance()
305
+ ]);
306
+ const types = resolvedValue(typesSettled, true);
307
+ const nfts = await getNftCollectionNfts(address, provider, types, maxNfts);
308
+ const metrics = getNftCollectionMetrics(nfts);
309
+ const archivist = resolvedValue(archivistSettled);
310
+ const [sources] = await Promise.all([
311
+ // Hash all the payloads
312
+ Promise.all(nfts.map((nft) => import_payload_builder.PayloadBuilder.dataHash(nft))),
313
+ // Insert them into the archivist if we have one
314
+ archivist ? archivist.insert(nfts) : NoOp
315
+ ]);
316
+ const payload = {
317
+ address,
318
+ chainId,
319
+ metrics,
320
+ name: resolvedValue(name, true),
321
+ schema: import_crypto_nft_collection_payload_plugin.NftCollectionSchema,
322
+ sources,
323
+ symbol: resolvedValue(symbol, true),
324
+ total: Number(resolvedValue(total, true)),
325
+ type: types.at(0),
326
+ types
327
+ };
328
+ return payload;
329
+ }));
284
330
  return observations.flat();
285
331
  }
286
332
  };
287
333
 
288
334
  // src/Plugin.ts
289
- var CryptoNftCollectionWitnessPlugin = () => (0, import_payloadset_plugin.createPayloadSetWitnessPlugin)(
290
- { required: { [import_crypto_nft_payload_plugin2.NftSchema]: 1 }, schema: import_payload_model.PayloadSetSchema },
291
- {
292
- witness: async (params) => {
293
- const result = await CryptoNftCollectionWitness.create(params);
294
- return result;
295
- }
296
- }
297
- );
335
+ var CryptoNftCollectionWitnessPlugin = /* @__PURE__ */ __name(() => (0, import_payloadset_plugin.createPayloadSetWitnessPlugin)({
336
+ required: {
337
+ [import_crypto_nft_payload_plugin2.NftSchema]: 1
338
+ },
339
+ schema: import_payload_model.PayloadSetSchema
340
+ }, {
341
+ witness: /* @__PURE__ */ __name(async (params) => {
342
+ const result = await CryptoNftCollectionWitness.create(params);
343
+ return result;
344
+ }, "witness")
345
+ }), "CryptoNftCollectionWitnessPlugin");
298
346
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.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/Plugin.ts","../../src/Witness.ts"],"sourcesContent":["export * from './lib/index.js'\n// eslint-disable-next-line import/no-default-export\nexport { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.js'\nexport * from './Witness.js'\n","import { Distribution } from './distribution.js'\n\nexport const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {\n const distribution: Distribution<T> = {}\n\n for (const item of array) {\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/index.js'\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 { assertEx } from '@xylabs/assert'\nimport { Interface, Provider } from 'ethers'\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 (const functionName of functionNames) {\n const selector = assertEx(contractInterface.getFunction(functionName)?.selector, () => 'Function not found on interface')\n if (!bytecode.includes(selector.slice(2))) {\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 { AxiosJson } from '@xylabs/axios'\nimport { exists } from '@xylabs/exists'\nimport { isHexZero } from '@xylabs/hex'\nimport { NftInfo, NftMetadata, NftSchema, TokenType, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { getErc1822SlotStatus } from '@xyo-network/erc1822-witness'\nimport { getErc1967SlotStatus } from '@xyo-network/erc1967-witness'\nimport { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { checkIpfsUrl } from '@xyo-network/witness-blockchain-abstract'\nimport { Provider } from 'ethers'\n\nimport { tokenTypes } from './tokenTypes.js'\nimport { tryCall } from './tryCall.js'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\nfunction range(size: number, startAt: number = 0): ReadonlyArray<number> {\n return [...Array(size).keys()].map((i) => i + startAt)\n}\n\nexport const getNftCollectionNfts = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: Provider,\n types?: TokenType[],\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n maxNfts = 100,\n): Promise<NftInfo[]> => {\n try {\n const block = await provider.getBlockNumber()\n\n //Check if ERC-1967 Upgradeable\n const erc1967Status = await getErc1967SlotStatus(provider, contractAddress, block)\n\n //Check if ERC-1822 Upgradeable\n const erc1822Status = await getErc1822SlotStatus(provider, contractAddress, block)\n\n const implementation =\n !erc1967Status.slots.implementation || isHexZero(erc1967Status.slots.implementation) ?\n erc1822Status.implementation\n : erc1967Status.implementation\n\n const axios = new AxiosJson({ timeout: 2000 })\n const enumerable = ERC721Enumerable__factory.connect(implementation, provider)\n const storage = ERC721URIStorage__factory.connect(implementation, provider)\n const supply1155 = ERC1155Supply__factory.connect(implementation, provider)\n const finalTypes = types ?? (await tokenTypes(provider, implementation))\n\n const maxNftsArray = range(maxNfts)\n\n const result: NftInfo[] = (\n await Promise.all(\n maxNftsArray.map(async (_value, i) => {\n const tokenId = (await tryCall(async () => await enumerable.tokenByIndex(i, { blockTag: block }))) ?? BigInt(i)\n if (tokenId !== undefined) {\n const supply =\n finalTypes.includes(toTokenType('ERC1155')) ?\n (await tryCall(async () => await supply1155['totalSupply(uint256)'](tokenId))) ?? '0x01'\n : '0x01'\n const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, { blockTag: block }))\n const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : undefined\n let metadata: NftMetadata | undefined\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: Number((await provider.getNetwork()).chainId),\n metadata,\n metadataUri,\n schema: NftSchema,\n supply: `0x${supply.toString(16)}`,\n tokenId: `0x${tokenId.toString(16)}`,\n type: finalTypes.at(0),\n types: finalTypes,\n }\n if (implementation !== contractAddress) {\n info.implementation = implementation\n }\n return info\n }\n }),\n )\n ).filter(exists)\n return result\n } catch (ex) {\n const error = ex as Error\n console.error(`getNftCollectionNfts failed: [${error.name}] ${error.message}`)\n console.log(error.stack)\n return []\n }\n}\n","import { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155URIStorage__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { Provider } from 'ethers'\n\nimport { contractHasFunctions } from './contractHasFunctions.js'\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, ERC721__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 { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin, PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness.js'\n\nexport const CryptoNftCollectionWitnessPlugin = (): PayloadSetWitnessPlugin<CryptoNftCollectionWitness> =>\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 {\n isNftCollectionWitnessQuery,\n NftCollectionInfo,\n NftCollectionSchema,\n NftCollectionWitnessConfig,\n NftCollectionWitnessConfigSchema,\n NftCollectionWitnessQuery,\n} from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { ERC721Enumerable__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Schema } from '@xyo-network/payload-model'\nimport { AbstractEvmWitness, EvmWitnessParams } from '@xyo-network/witness-evm-abstract'\n\nimport { getNftCollectionMetrics, getNftCollectionNfts, tokenTypes } from './lib/index.js'\n\nexport type CryptoNftCollectionWitnessParams = EvmWitnessParams<NftCollectionWitnessConfig>\n\nconst defaultMaxNfts = 100\n\n/**\n * A \"no operation\" Promise to be used\n * when no action is desired but a Promise\n * is required to be returned\n */\nconst NoOp = Promise.resolve()\n\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert: true): T\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: false): T | undefined\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: boolean) {\n if (assert && settled.status === 'rejected') {\n throw settled.reason\n }\n return settled.status === 'fulfilled' ? settled.value : undefined\n}\n\nexport class CryptoNftCollectionWitness<\n TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams,\n> extends AbstractEvmWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, NftCollectionWitnessConfigSchema]\n static override readonly defaultConfigSchema: Schema = NftCollectionWitnessConfigSchema\n\n protected override async observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]> {\n await this.started('throw')\n await this.getProviders() //make sure cache clears\n const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map<Promise<NftCollectionInfo>>(async (query) => {\n const chainId = assertEx(query?.chainId || this.config.chainId, () => 'params.chainId is required')\n const provider = await this.getProvider(true, true)\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, () => 'params.address is required')),\n () => 'Failed to parse params.address',\n ).toString()\n\n const erc721Enumerable = ERC721Enumerable__factory.connect(address, provider)\n\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([\n erc721Enumerable.name(),\n erc721Enumerable.symbol(),\n erc721Enumerable.totalSupply(),\n tokenTypes(provider, address),\n this.archivistInstance(),\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) => PayloadBuilder.dataHash(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: Number(resolvedValue(total, true)),\n type: types.at(0),\n types,\n }\n return payload\n }),\n )\n return observations.flat()\n }\n}\n"],"mappings":"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","names":["attributes","p","import_open_zeppelin_typechain","import_crypto_nft_payload_plugin","import_assert","import_open_zeppelin_typechain"]}
1
+ {"version":3,"sources":["../../src/index.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/Plugin.ts","../../src/Witness.ts"],"sourcesContent":["export * from './lib/index.ts'\n// eslint-disable-next-line import/no-default-export\nexport { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.ts'\nexport * from './Witness.ts'\n","import { Distribution } from './distribution.ts'\n\nexport const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {\n const distribution: Distribution<T> = {}\n\n for (const item of array) {\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/index.ts'\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 { assertEx } from '@xylabs/assert'\nimport { Interface, Provider } from 'ethers'\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 (const functionName of functionNames) {\n const selector = assertEx(contractInterface.getFunction(functionName)?.selector, () => 'Function not found on interface')\n if (!bytecode.includes(selector.slice(2))) {\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 { AxiosJson } from '@xylabs/axios'\nimport { exists } from '@xylabs/exists'\nimport { isHexZero } from '@xylabs/hex'\nimport { NftInfo, NftMetadata, NftSchema, TokenType, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { getErc1822SlotStatus } from '@xyo-network/erc1822-witness'\nimport { getErc1967SlotStatus } from '@xyo-network/erc1967-witness'\nimport { ERC721Enumerable__factory, ERC721URIStorage__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { checkIpfsUrl } from '@xyo-network/witness-blockchain-abstract'\nimport { Provider } from 'ethers'\n\nimport { tokenTypes } from './tokenTypes.ts'\nimport { tryCall } from './tryCall.ts'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\nfunction range(size: number, startAt: number = 0): ReadonlyArray<number> {\n return [...Array(size).keys()].map(i => i + startAt)\n}\n\nexport const getNftCollectionNfts = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: Provider,\n types?: TokenType[],\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n maxNfts = 100,\n): Promise<NftInfo[]> => {\n try {\n const block = await provider.getBlockNumber()\n\n // Check if ERC-1967 Upgradeable\n const erc1967Status = await getErc1967SlotStatus(provider, contractAddress, block)\n\n // Check if ERC-1822 Upgradeable\n const erc1822Status = await getErc1822SlotStatus(provider, contractAddress, block)\n\n const implementation\n = !erc1967Status.slots.implementation || isHexZero(erc1967Status.slots.implementation)\n ? erc1822Status.implementation\n : erc1967Status.implementation\n\n const axios = new AxiosJson({ timeout: 2000 })\n const enumerable = ERC721Enumerable__factory.connect(implementation, provider)\n const storage = ERC721URIStorage__factory.connect(implementation, provider)\n const supply1155 = ERC1155Supply__factory.connect(implementation, provider)\n const finalTypes = types ?? (await tokenTypes(provider, implementation))\n\n const maxNftsArray = range(maxNfts)\n\n const result: NftInfo[] = (\n await Promise.all(\n maxNftsArray.map(async (_value, i) => {\n const tokenId = (await tryCall(async () => await enumerable.tokenByIndex(i, { blockTag: block }))) ?? BigInt(i)\n if (tokenId !== undefined) {\n const supply\n = finalTypes.includes(toTokenType('ERC1155'))\n ? ((await tryCall(async () => await supply1155['totalSupply(uint256)'](tokenId))) ?? '0x01')\n : '0x01'\n const metadataUri = await tryCall(async () => await storage.tokenURI(tokenId, { blockTag: block }))\n const checkedMetaDataUri = metadataUri ? checkIpfsUrl(metadataUri, ipfsGateway) : undefined\n let metadata: NftMetadata | undefined\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: Number((await provider.getNetwork()).chainId),\n metadata,\n metadataUri,\n schema: NftSchema,\n supply: `0x${supply.toString(16)}`,\n tokenId: `0x${tokenId.toString(16)}`,\n type: finalTypes.at(0),\n types: finalTypes,\n }\n if (implementation !== contractAddress) {\n info.implementation = implementation\n }\n return info\n }\n }),\n )\n ).filter(exists)\n return result\n } catch (ex) {\n const error = ex as Error\n console.error(`getNftCollectionNfts failed: [${error.name}] ${error.message}`)\n console.log(error.stack)\n return []\n }\n}\n","import { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155URIStorage__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { Provider } from 'ethers'\n\nimport { contractHasFunctions } from './contractHasFunctions.ts'\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, ERC721__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 { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin, PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness.ts'\n\nexport const CryptoNftCollectionWitnessPlugin = (): PayloadSetWitnessPlugin<CryptoNftCollectionWitness> =>\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 {\n isNftCollectionWitnessQuery,\n NftCollectionInfo,\n NftCollectionSchema,\n NftCollectionWitnessConfig,\n NftCollectionWitnessConfigSchema,\n NftCollectionWitnessQuery,\n} from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { ERC721Enumerable__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { PayloadBuilder } from '@xyo-network/payload-builder'\nimport { Schema } from '@xyo-network/payload-model'\nimport { AbstractEvmWitness, EvmWitnessParams } from '@xyo-network/witness-evm-abstract'\n\nimport { getNftCollectionMetrics, getNftCollectionNfts, tokenTypes } from './lib/index.ts'\n\nexport type CryptoNftCollectionWitnessParams = EvmWitnessParams<NftCollectionWitnessConfig>\n\nconst defaultMaxNfts = 100\n\n/**\n * A \"no operation\" Promise to be used\n * when no action is desired but a Promise\n * is required to be returned\n */\nconst NoOp = Promise.resolve()\n\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert: true): T\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: false): T | undefined\nfunction resolvedValue<T>(settled: PromiseSettledResult<T>, assert?: boolean) {\n if (assert && settled.status === 'rejected') {\n throw settled.reason\n }\n return settled.status === 'fulfilled' ? settled.value : undefined\n}\n\nexport class CryptoNftCollectionWitness<\n TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams,\n> extends AbstractEvmWitness<TParams, NftCollectionWitnessQuery, NftCollectionInfo> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, NftCollectionWitnessConfigSchema]\n static override readonly defaultConfigSchema: Schema = NftCollectionWitnessConfigSchema\n\n protected override async observeHandler(payloads?: NftCollectionWitnessQuery[]): Promise<NftCollectionInfo[]> {\n await this.started('throw')\n await this.getProviders() // make sure cache clears\n const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map<Promise<NftCollectionInfo>>(async (query) => {\n const chainId = assertEx(query?.chainId || this.config.chainId, () => 'params.chainId is required')\n const provider = await this.getProvider(true, true)\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, () => 'params.address is required')),\n () => 'Failed to parse params.address',\n ).toString()\n\n const erc721Enumerable = ERC721Enumerable__factory.connect(address, provider)\n\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [name, symbol, total, typesSettled, archivistSettled] = await Promise.allSettled([\n erc721Enumerable.name(),\n erc721Enumerable.symbol(),\n erc721Enumerable.totalSupply(),\n tokenTypes(provider, address),\n this.archivistInstance(),\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 => PayloadBuilder.dataHash(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: Number(resolvedValue(total, true)),\n type: types.at(0),\n types,\n }\n return payload\n }),\n )\n return observations.flat()\n }\n}\n"],"mappings":"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","names":["calculateAllPropertiesDistribution","array","distribution","item","property","Object","prototype","hasOwnProperty","call","value","undefined","valueString","toString","calculateBinomialParamsFromProbability","n","p","mean","variance","stdDev","Math","sqrt","getNftCollectionMetrics","nfts","traits","map","nft","metadata","attributes","filter","v","undefined","Object","fromEntries","attribute","trait_type","value","distribution","calculateAllPropertiesDistribution","n","length","entries","trait","traitCount","values","reduce","prev","curr","p","calculateBinomialParamsFromProbability","traitValueCount","metrics","binomial","count","contractHasFunctions","provider","address","contractInterface","functionNames","bytecode","getCode","functionName","selector","assertEx","getFunction","includes","slice","ex","error","console","log","import_open_zeppelin_typechain","isErc1155","provider","address","contractHasFunctions","ERC1155URIStorage__factory","createInterface","isErc721","ERC721__factory","tokenTypes","erc721","erc1155","Promise","all","result","push","tryCall","func","name","ex","error","console","log","message","undefined","ipfsGateway","range","size","startAt","Array","keys","map","i","getNftCollectionNfts","contractAddress","provider","types","maxNfts","block","getBlockNumber","erc1967Status","getErc1967SlotStatus","erc1822Status","getErc1822SlotStatus","implementation","slots","isHexZero","axios","AxiosJson","timeout","enumerable","ERC721Enumerable__factory","connect","storage","ERC721URIStorage__factory","supply1155","ERC1155Supply__factory","finalTypes","tokenTypes","maxNftsArray","result","Promise","all","_value","tokenId","tryCall","tokenByIndex","blockTag","BigInt","undefined","supply","includes","toTokenType","metadataUri","tokenURI","checkedMetaDataUri","checkIpfsUrl","metadata","get","data","ex","error","console","message","info","address","chainId","Number","getNetwork","schema","NftSchema","toString","type","at","filter","exists","name","log","stack","import_crypto_nft_payload_plugin","import_assert","import_open_zeppelin_typechain","defaultMaxNfts","NoOp","Promise","resolve","resolvedValue","settled","assert","status","reason","value","undefined","CryptoNftCollectionWitness","AbstractEvmWitness","configSchemas","NftCollectionWitnessConfigSchema","defaultConfigSchema","observeHandler","payloads","started","getProviders","queries","filter","isNftCollectionWitnessQuery","observations","all","map","query","chainId","assertEx","config","provider","getProvider","address","EthAddress","parse","toString","erc721Enumerable","ERC721Enumerable__factory","connect","maxNfts","name","symbol","total","typesSettled","archivistSettled","allSettled","totalSupply","tokenTypes","archivistInstance","types","nfts","getNftCollectionNfts","metrics","getNftCollectionMetrics","archivist","sources","nft","PayloadBuilder","dataHash","insert","payload","schema","NftCollectionSchema","Number","type","at","flat","CryptoNftCollectionWitnessPlugin","createPayloadSetWitnessPlugin","required","NftSchema","schema","PayloadSetSchema","witness","params","result","CryptoNftCollectionWitness","create"]}
@@ -1,4 +1,4 @@
1
- export * from './lib/index.js';
2
- export { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.js';
3
- export * from './Witness.js';
1
+ export * from './lib/index.ts';
2
+ export { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.ts';
3
+ export * from './Witness.ts';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- export * from './lib/index.js';
2
- export { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.js';
3
- export * from './Witness.js';
1
+ export * from './lib/index.ts';
2
+ export { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.ts';
3
+ export * from './Witness.ts';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- export * from './lib/index.js';
2
- export { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.js';
3
- export * from './Witness.js';
1
+ export * from './lib/index.ts';
2
+ export { CryptoNftCollectionWitnessPlugin, CryptoNftCollectionWitnessPlugin as default } from './Plugin.ts';
3
+ export * from './Witness.ts';
4
4
  //# sourceMappingURL=index.d.ts.map