@xyo-network/crypto-nft-collection-witness-plugin 2.75.0 → 2.75.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/dist/browser/Plugin.d.cts +56 -0
  2. package/dist/browser/Plugin.d.cts.map +1 -0
  3. package/dist/browser/Plugin.js +4 -169
  4. package/dist/browser/Plugin.js.map +1 -1
  5. package/dist/browser/Witness.d.cts +10 -0
  6. package/dist/browser/Witness.d.cts.map +1 -0
  7. package/dist/browser/Witness.js +5 -126
  8. package/dist/browser/Witness.js.map +1 -1
  9. package/dist/browser/index.d.cts +6 -0
  10. package/dist/browser/index.d.cts.map +1 -0
  11. package/dist/browser/index.js +4 -186
  12. package/dist/browser/index.js.map +1 -1
  13. package/dist/browser/lib/collectionMetrics/getNftCollectionMetrics.d.cts +4 -0
  14. package/dist/browser/lib/collectionMetrics/getNftCollectionMetrics.d.cts.map +1 -0
  15. package/dist/browser/lib/collectionMetrics/getNftCollectionMetrics.js +2 -35
  16. package/dist/browser/lib/collectionMetrics/getNftCollectionMetrics.js.map +1 -1
  17. package/dist/browser/lib/collectionMetrics/index.d.cts +2 -0
  18. package/dist/browser/lib/collectionMetrics/index.d.cts.map +1 -0
  19. package/dist/browser/lib/collectionMetrics/index.js +1 -59
  20. package/dist/browser/lib/collectionMetrics/index.js.map +1 -1
  21. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts +3 -0
  22. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts.map +1 -0
  23. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js +1 -2
  24. package/dist/browser/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js.map +1 -1
  25. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts +3 -0
  26. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts.map +1 -0
  27. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.js +1 -2
  28. package/dist/browser/lib/collectionMetrics/lib/calculatePropertyDistribution.js.map +1 -1
  29. package/dist/browser/lib/collectionMetrics/lib/distribution.d.cts +6 -0
  30. package/dist/browser/lib/collectionMetrics/lib/distribution.d.cts.map +1 -0
  31. package/dist/browser/lib/collectionMetrics/lib/index.d.cts +4 -0
  32. package/dist/browser/lib/collectionMetrics/lib/index.d.cts.map +1 -0
  33. package/dist/browser/lib/collectionMetrics/lib/index.js +3 -48
  34. package/dist/browser/lib/collectionMetrics/lib/index.js.map +1 -1
  35. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.d.cts +8 -0
  36. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.d.cts.map +1 -0
  37. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.js +1 -2
  38. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.js.map +1 -1
  39. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.d.cts +9 -0
  40. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.d.cts.map +1 -0
  41. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.js +1 -2
  42. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.js.map +1 -1
  43. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts +3 -0
  44. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts.map +1 -0
  45. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.js +2 -22
  46. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.js.map +1 -1
  47. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts +2 -0
  48. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts.map +1 -0
  49. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.js +1 -22
  50. package/dist/browser/lib/collectionMetrics/lib/probabilityDistributions/index.js.map +1 -1
  51. package/dist/browser/lib/getNftCollectionCount.d.cts +2 -0
  52. package/dist/browser/lib/getNftCollectionCount.d.cts.map +1 -0
  53. package/dist/browser/lib/getNftCollectionCount.js +2 -10
  54. package/dist/browser/lib/getNftCollectionCount.js.map +1 -1
  55. package/dist/browser/lib/getNftCollectionMetadata.d.cts +3 -0
  56. package/dist/browser/lib/getNftCollectionMetadata.d.cts.map +1 -0
  57. package/dist/browser/lib/getNftCollectionMetadata.js +2 -10
  58. package/dist/browser/lib/getNftCollectionMetadata.js.map +1 -1
  59. package/dist/browser/lib/getNftCollectionNfts.d.cts +3 -0
  60. package/dist/browser/lib/getNftCollectionNfts.d.cts.map +1 -0
  61. package/dist/browser/lib/getNftCollectionNfts.js +2 -10
  62. package/dist/browser/lib/getNftCollectionNfts.js.map +1 -1
  63. package/dist/browser/lib/index.d.cts +5 -0
  64. package/dist/browser/lib/index.d.cts.map +1 -0
  65. package/dist/browser/lib/index.js +4 -124
  66. package/dist/browser/lib/index.js.map +1 -1
  67. package/dist/browser/lib/nonEvaluableContractAddresses.d.cts +6 -0
  68. package/dist/browser/lib/nonEvaluableContractAddresses.d.cts.map +1 -0
  69. package/dist/browser/lib/nonEvaluableContractAddresses.js +1 -2
  70. package/dist/browser/lib/nonEvaluableContractAddresses.js.map +1 -1
  71. package/dist/docs.json +22903 -0
  72. package/dist/node/Plugin.d.cts +56 -0
  73. package/dist/node/Plugin.d.cts.map +1 -0
  74. package/dist/node/Plugin.js +170 -5
  75. package/dist/node/Plugin.js.map +1 -1
  76. package/dist/node/Plugin.mjs +172 -4
  77. package/dist/node/Plugin.mjs.map +1 -1
  78. package/dist/node/Witness.d.cts +10 -0
  79. package/dist/node/Witness.d.cts.map +1 -0
  80. package/dist/node/Witness.js +138 -13
  81. package/dist/node/Witness.js.map +1 -1
  82. package/dist/node/Witness.mjs +133 -9
  83. package/dist/node/Witness.mjs.map +1 -1
  84. package/dist/node/index.d.cts +6 -0
  85. package/dist/node/index.d.cts.map +1 -0
  86. package/dist/node/index.js +195 -9
  87. package/dist/node/index.js.map +1 -1
  88. package/dist/node/index.mjs +189 -4
  89. package/dist/node/index.mjs.map +1 -1
  90. package/dist/node/lib/collectionMetrics/getNftCollectionMetrics.d.cts +4 -0
  91. package/dist/node/lib/collectionMetrics/getNftCollectionMetrics.d.cts.map +1 -0
  92. package/dist/node/lib/collectionMetrics/getNftCollectionMetrics.js +45 -6
  93. package/dist/node/lib/collectionMetrics/getNftCollectionMetrics.js.map +1 -1
  94. package/dist/node/lib/collectionMetrics/getNftCollectionMetrics.mjs +39 -3
  95. package/dist/node/lib/collectionMetrics/getNftCollectionMetrics.mjs.map +1 -1
  96. package/dist/node/lib/collectionMetrics/index.d.cts +2 -0
  97. package/dist/node/lib/collectionMetrics/index.d.cts.map +1 -0
  98. package/dist/node/lib/collectionMetrics/index.js +70 -3
  99. package/dist/node/lib/collectionMetrics/index.js.map +1 -1
  100. package/dist/node/lib/collectionMetrics/index.mjs +62 -1
  101. package/dist/node/lib/collectionMetrics/index.mjs.map +1 -1
  102. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts +3 -0
  103. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.cts.map +1 -0
  104. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js +3 -1
  105. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js.map +1 -1
  106. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.mjs +2 -1
  107. package/dist/node/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.mjs.map +1 -1
  108. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts +3 -0
  109. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.d.cts.map +1 -0
  110. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.js +3 -1
  111. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.js.map +1 -1
  112. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.mjs +2 -1
  113. package/dist/node/lib/collectionMetrics/lib/calculatePropertyDistribution.mjs.map +1 -1
  114. package/dist/node/lib/collectionMetrics/lib/distribution.d.cts +6 -0
  115. package/dist/node/lib/collectionMetrics/lib/distribution.d.cts.map +1 -0
  116. package/dist/node/lib/collectionMetrics/lib/distribution.js +2 -0
  117. package/dist/node/lib/collectionMetrics/lib/distribution.js.map +1 -1
  118. package/dist/node/lib/collectionMetrics/lib/index.d.cts +4 -0
  119. package/dist/node/lib/collectionMetrics/lib/index.d.cts.map +1 -0
  120. package/dist/node/lib/collectionMetrics/lib/index.js +58 -7
  121. package/dist/node/lib/collectionMetrics/lib/index.js.map +1 -1
  122. package/dist/node/lib/collectionMetrics/lib/index.mjs +48 -3
  123. package/dist/node/lib/collectionMetrics/lib/index.mjs.map +1 -1
  124. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.d.cts +8 -0
  125. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.d.cts.map +1 -0
  126. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.js +3 -1
  127. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.js.map +1 -1
  128. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.mjs +2 -1
  129. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromOutcomes.mjs.map +1 -1
  130. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.d.cts +9 -0
  131. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.d.cts.map +1 -0
  132. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.js +3 -1
  133. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.js.map +1 -1
  134. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.mjs +2 -1
  135. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.mjs.map +1 -1
  136. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts +3 -0
  137. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.d.cts.map +1 -0
  138. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.js +31 -5
  139. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.js.map +1 -1
  140. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.mjs +22 -2
  141. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/binomial/index.mjs.map +1 -1
  142. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts +2 -0
  143. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.d.cts.map +1 -0
  144. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.js +31 -3
  145. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.js.map +1 -1
  146. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.mjs +22 -1
  147. package/dist/node/lib/collectionMetrics/lib/probabilityDistributions/index.mjs.map +1 -1
  148. package/dist/node/lib/getNftCollectionCount.d.cts +2 -0
  149. package/dist/node/lib/getNftCollectionCount.d.cts.map +1 -0
  150. package/dist/node/lib/getNftCollectionCount.js +12 -3
  151. package/dist/node/lib/getNftCollectionCount.js.map +1 -1
  152. package/dist/node/lib/getNftCollectionCount.mjs +10 -2
  153. package/dist/node/lib/getNftCollectionCount.mjs.map +1 -1
  154. package/dist/node/lib/getNftCollectionMetadata.d.cts +3 -0
  155. package/dist/node/lib/getNftCollectionMetadata.d.cts.map +1 -0
  156. package/dist/node/lib/getNftCollectionMetadata.js +12 -3
  157. package/dist/node/lib/getNftCollectionMetadata.js.map +1 -1
  158. package/dist/node/lib/getNftCollectionMetadata.mjs +10 -2
  159. package/dist/node/lib/getNftCollectionMetadata.mjs.map +1 -1
  160. package/dist/node/lib/getNftCollectionNfts.d.cts +3 -0
  161. package/dist/node/lib/getNftCollectionNfts.d.cts.map +1 -0
  162. package/dist/node/lib/getNftCollectionNfts.js +12 -3
  163. package/dist/node/lib/getNftCollectionNfts.js.map +1 -1
  164. package/dist/node/lib/getNftCollectionNfts.mjs +10 -2
  165. package/dist/node/lib/getNftCollectionNfts.mjs.map +1 -1
  166. package/dist/node/lib/index.d.cts +5 -0
  167. package/dist/node/lib/index.d.cts.map +1 -0
  168. package/dist/node/lib/index.js +138 -9
  169. package/dist/node/lib/index.js.map +1 -1
  170. package/dist/node/lib/index.mjs +127 -4
  171. package/dist/node/lib/index.mjs.map +1 -1
  172. package/dist/node/lib/nonEvaluableContractAddresses.d.cts +6 -0
  173. package/dist/node/lib/nonEvaluableContractAddresses.d.cts.map +1 -0
  174. package/dist/node/lib/nonEvaluableContractAddresses.js +3 -1
  175. package/dist/node/lib/nonEvaluableContractAddresses.js.map +1 -1
  176. package/dist/node/lib/nonEvaluableContractAddresses.mjs +2 -1
  177. package/dist/node/lib/nonEvaluableContractAddresses.mjs.map +1 -1
  178. package/package.json +13 -13
@@ -15,22 +15,208 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
20
21
  var src_exports = {};
21
22
  __export(src_exports, {
22
- CryptoNftCollectionWitnessPlugin: () => import_Plugin.CryptoNftCollectionWitnessPlugin,
23
- default: () => src_default
23
+ CryptoNftCollectionWitness: () => CryptoNftCollectionWitness,
24
+ CryptoNftCollectionWitnessPlugin: () => CryptoNftCollectionWitnessPlugin,
25
+ default: () => src_default,
26
+ getNftCollectionCount: () => getNftCollectionCount,
27
+ getNftCollectionMetadata: () => getNftCollectionMetadata,
28
+ getNftCollectionMetrics: () => getNftCollectionMetrics,
29
+ getNftCollectionNfts: () => getNftCollectionNfts
24
30
  });
25
31
  module.exports = __toCommonJS(src_exports);
26
- var import_Plugin = require("./Plugin");
27
- __reExport(src_exports, require("./lib"), module.exports);
28
- __reExport(src_exports, require("./Witness"), module.exports);
29
- var src_default = import_Plugin.CryptoNftCollectionWitnessPlugin;
32
+
33
+ // src/Plugin.ts
34
+ var import_crypto_nft_payload_plugin3 = require("@xyo-network/crypto-nft-payload-plugin");
35
+ var import_payload_model = require("@xyo-network/payload-model");
36
+ var import_payloadset_plugin = require("@xyo-network/payloadset-plugin");
37
+
38
+ // src/Witness.ts
39
+ var import_assert = require("@xylabs/assert");
40
+ var import_core = require("@xyo-network/core");
41
+ var import_crypto_nft_collection_payload_plugin = require("@xyo-network/crypto-nft-collection-payload-plugin");
42
+ var import_witness = require("@xyo-network/witness");
43
+
44
+ // src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
45
+ var calculateAllPropertiesDistribution = (array) => {
46
+ const distribution = {};
47
+ array.forEach((item) => {
48
+ for (const property in item) {
49
+ if (Object.prototype.hasOwnProperty.call(item, property)) {
50
+ const value = item[property];
51
+ if (value !== void 0 && value !== null) {
52
+ const valueString = value.toString();
53
+ if (!distribution[property]) {
54
+ distribution[property] = { [valueString]: 1 };
55
+ } else if (!distribution[property][valueString]) {
56
+ ;
57
+ distribution[property][valueString] = 1;
58
+ } else {
59
+ ;
60
+ distribution[property][valueString] += 1;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ });
66
+ return distribution;
67
+ };
68
+
69
+ // src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts
70
+ var calculateBinomialParamsFromProbability = (n, p) => {
71
+ const mean = n * p;
72
+ const variance = n * p * (1 - p);
73
+ const stdDev = Math.sqrt(variance);
74
+ return { mean, p, stdDev, variance };
75
+ };
76
+
77
+ // src/lib/collectionMetrics/getNftCollectionMetrics.ts
78
+ var getNftCollectionMetrics = (nfts) => {
79
+ const traits = nfts.map((nft) => {
80
+ var _a;
81
+ return (_a = nft == null ? void 0 : nft.metadata) == null ? void 0 : _a.attributes;
82
+ }).filter((v) => v !== void 0).map((attributes2) => {
83
+ return Object.fromEntries(attributes2.map((attribute) => [attribute.trait_type, attribute.value]));
84
+ });
85
+ const distribution = calculateAllPropertiesDistribution(traits);
86
+ const n = nfts.length;
87
+ const attributes = Object.fromEntries(
88
+ Object.entries(distribution).filter((v) => v[1] !== void 0).map(([trait, entries]) => {
89
+ const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0);
90
+ const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n);
91
+ const values = Object.fromEntries(
92
+ Object.entries(entries).map(([value, traitValueCount]) => {
93
+ const { p: p2 } = calculateBinomialParamsFromProbability(n, traitValueCount / n);
94
+ const metrics = { binomial: { p: p2 }, count: traitValueCount };
95
+ return [value, metrics];
96
+ })
97
+ );
98
+ return [trait, { metrics: { binomial: { p }, count: traitCount }, values }];
99
+ })
100
+ );
101
+ return { metadata: { attributes } };
102
+ };
103
+
104
+ // src/lib/getNftCollectionCount.ts
105
+ var import_sdk = require("@infura/sdk");
106
+
107
+ // src/lib/nonEvaluableContractAddresses.ts
108
+ var nonEvaluableContractAddresses = [
109
+ // ENS
110
+ "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72"
111
+ ].map((address) => address.toUpperCase());
112
+
113
+ // src/lib/getNftCollectionCount.ts
114
+ var getNftCollectionCount = async (contractAddress, chainId, privateKey) => {
115
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
116
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
117
+ }
118
+ const sdk = new import_sdk.SDK(new import_sdk.Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
119
+ const opts = { contractAddress };
120
+ const { total } = await sdk.api.getNFTsForCollection(opts);
121
+ return total;
122
+ };
123
+
124
+ // src/lib/getNftCollectionMetadata.ts
125
+ var import_sdk2 = require("@infura/sdk");
126
+ var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
127
+ var getNftCollectionMetadata = async (contractAddress, chainId, privateKey) => {
128
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
129
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
130
+ }
131
+ const sdk = new import_sdk2.SDK(new import_sdk2.Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
132
+ const opts = { contractAddress };
133
+ const { name, symbol, tokenType } = await sdk.api.getContractMetadata(opts);
134
+ const type = (0, import_crypto_nft_payload_plugin.toTokenType)(tokenType);
135
+ return { address: contractAddress, chainId, name, symbol, type };
136
+ };
137
+
138
+ // src/lib/getNftCollectionNfts.ts
139
+ var import_sdk3 = require("@infura/sdk");
140
+ var import_crypto_nft_payload_plugin2 = require("@xyo-network/crypto-nft-payload-plugin");
141
+ var getNftCollectionNfts = async (contractAddress, chainId, privateKey, maxNfts = 100) => {
142
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
143
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
144
+ }
145
+ const sdk = new import_sdk3.SDK(new import_sdk3.Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
146
+ const nfts = [];
147
+ let cursor = void 0;
148
+ do {
149
+ const opts = { contractAddress, cursor };
150
+ const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTsForCollection(opts);
151
+ const batch = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {
152
+ const { contract: address, type: tokenType, ...rest } = asset;
153
+ const type = (0, import_crypto_nft_payload_plugin2.toTokenType)(tokenType);
154
+ return { address, chainId, type, ...rest };
155
+ });
156
+ nfts.push(...batch);
157
+ cursor = nextCursor;
158
+ if (nfts.length >= total || !cursor)
159
+ break;
160
+ } while (nfts.length < maxNfts);
161
+ return nfts.map((nft) => {
162
+ return { ...nft, schema: import_crypto_nft_payload_plugin2.NftSchema };
163
+ });
164
+ };
165
+
166
+ // src/Witness.ts
167
+ var defaultMaxNfts = 100;
168
+ var NoOp = Promise.resolve();
169
+ var CryptoNftCollectionWitness = class extends import_witness.AbstractWitness {
170
+ static configSchemas = [import_crypto_nft_collection_payload_plugin.NftCollectionWitnessConfigSchema];
171
+ async observeHandler(payloads) {
172
+ await this.started("throw");
173
+ const queries = (payloads == null ? void 0 : payloads.filter(import_crypto_nft_collection_payload_plugin.isNftCollectionWitnessQuery)) ?? [];
174
+ const observations = await Promise.all(
175
+ queries.map(async (query) => {
176
+ const address = (0, import_assert.assertEx)((query == null ? void 0 : query.address) || this.config.address, "params.address is required");
177
+ const chainId = (0, import_assert.assertEx)((query == null ? void 0 : query.chainId) || this.config.chainId, "params.chainId is required");
178
+ const maxNfts = (query == null ? void 0 : query.maxNfts) || defaultMaxNfts;
179
+ const [info, total, nfts, archivist] = await Promise.all([
180
+ getNftCollectionMetadata(address, chainId, this.account.private.hex),
181
+ getNftCollectionCount(address, chainId, this.account.private.hex),
182
+ getNftCollectionNfts(address, chainId, this.account.private.hex, maxNfts),
183
+ this.writeArchivist()
184
+ ]);
185
+ const metrics = getNftCollectionMetrics(nfts);
186
+ const [sources] = await Promise.all([
187
+ // Hash all the payloads
188
+ Promise.all(nfts.map((nft) => import_core.PayloadHasher.hashAsync(nft))),
189
+ // Insert them into the archivist if we have one
190
+ archivist ? archivist.insert(nfts) : NoOp
191
+ ]);
192
+ const payload = { ...info, metrics, schema: import_crypto_nft_collection_payload_plugin.NftCollectionSchema, sources, total };
193
+ return payload;
194
+ })
195
+ );
196
+ return observations.flat();
197
+ }
198
+ };
199
+
200
+ // src/Plugin.ts
201
+ var CryptoNftCollectionWitnessPlugin = () => (0, import_payloadset_plugin.createPayloadSetWitnessPlugin)(
202
+ { required: { [import_crypto_nft_payload_plugin3.NftSchema]: 1 }, schema: import_payload_model.PayloadSetSchema },
203
+ {
204
+ witness: async (params) => {
205
+ const result = await CryptoNftCollectionWitness.create(params);
206
+ return result;
207
+ }
208
+ }
209
+ );
210
+
211
+ // src/index.ts
212
+ var src_default = CryptoNftCollectionWitnessPlugin;
30
213
  // Annotate the CommonJS export names for ESM import in node:
31
214
  0 && (module.exports = {
215
+ CryptoNftCollectionWitness,
32
216
  CryptoNftCollectionWitnessPlugin,
33
- ...require("./lib"),
34
- ...require("./Witness")
217
+ getNftCollectionCount,
218
+ getNftCollectionMetadata,
219
+ getNftCollectionMetrics,
220
+ getNftCollectionNfts
35
221
  });
36
222
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAiD;AAEjD,wBAAc,kBAFd;AAGA,wBAAc,sBAHd;AAQA,IAAO,cAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts","../../src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts","../../src/lib/collectionMetrics/getNftCollectionMetrics.ts","../../src/lib/getNftCollectionCount.ts","../../src/lib/nonEvaluableContractAddresses.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getNftCollectionNfts.ts"],"sourcesContent":["import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness'\n\nexport const CryptoNftCollectionWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoNftCollectionWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoNftCollectionWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { PayloadHasher } from '@xyo-network/core'\nimport {\n isNftCollectionWitnessQuery,\n NftCollectionInfo,\n NftCollectionSchema,\n NftCollectionWitnessConfig,\n NftCollectionWitnessConfigSchema,\n} from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractWitness, WitnessParams } from '@xyo-network/witness'\n\nimport { getNftCollectionCount, getNftCollectionMetadata, getNftCollectionMetrics, getNftCollectionNfts } from './lib'\n\nexport type CryptoNftCollectionWitnessParams = WitnessParams<AnyConfigSchema<NftCollectionWitnessConfig>>\n\nconst defaultMaxNfts = 100\n\n/**\n * A \"no operation\" Promise to be used\n * when no action is desired but a Promise\n * is required to be returned\n */\nconst NoOp = Promise.resolve()\n\nexport class CryptoNftCollectionWitness<\n TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams,\n> extends AbstractWitness<TParams> {\n static override configSchemas = [NftCollectionWitnessConfigSchema]\n\n protected override async observeHandler(payloads?: Payload[]): Promise<Payload[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map<Promise<NftCollectionInfo>>(async (query) => {\n const address = assertEx(query?.address || this.config.address, 'params.address is required')\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [info, total, nfts, archivist] = await Promise.all([\n getNftCollectionMetadata(address, chainId, this.account.private.hex),\n getNftCollectionCount(address, chainId, this.account.private.hex),\n getNftCollectionNfts(address, chainId, this.account.private.hex, maxNfts),\n this.writeArchivist(),\n ])\n const metrics = getNftCollectionMetrics(nfts)\n const [sources] = await Promise.all([\n // Hash all the payloads\n Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),\n // Insert them into the archivist if we have one\n archivist ? archivist.insert(nfts) : NoOp,\n ])\n const payload: NftCollectionInfo = { ...info, metrics, schema: NftCollectionSchema, sources, total }\n return payload\n }),\n )\n return observations.flat()\n }\n}\n","import { Distribution } from './distribution'\n\nexport const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {\n const distribution: Distribution<T> = {}\n\n array.forEach((item) => {\n for (const property in item) {\n if (Object.prototype.hasOwnProperty.call(item, property)) {\n const value = item[property as keyof T]\n if (value !== undefined && value !== null) {\n const valueString = value.toString()\n if (!distribution[property]) {\n distribution[property] = { [valueString]: 1 }\n } else if (!distribution[property]![valueString]) {\n ;(distribution[property] as Record<string, number>)[valueString] = 1\n } else {\n ;(distribution[property] as Record<string, number>)[valueString] += 1\n }\n }\n }\n }\n })\n\n return distribution\n}\n","import { BinomialDistributionParameters } from '@xyo-network/crypto-nft-collection-payload-plugin'\n\n/**\n * Calculates the parameters of a binomial distribution given the number of trials and success probability\n * @param n Number of trials\n * @param p Success probability\n * @returns The binomial distribution parameters\n */\nexport const calculateBinomialParamsFromProbability = (n: number, p: number): BinomialDistributionParameters => {\n // Mean (µ)\n const mean = n * p\n\n // Variance (σ^2)\n const variance = n * p * (1 - p)\n\n // Standard Deviation (σ)\n const stdDev = Math.sqrt(variance)\n\n return { mean, p, stdDev, variance }\n}\n","import { NftCollectionMetrics, NftTraitMetrics } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { NftInfoFields, OpenSeaNftAttribute } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { calculateAllPropertiesDistribution, calculateBinomialParamsFromProbability } from './lib'\n\ntype TraitDistributionEntry = [string, { [key: string]: number }]\n\nexport const getNftCollectionMetrics = (nfts: NftInfoFields[]): NftCollectionMetrics => {\n const traits = nfts\n .map((nft) => nft?.metadata?.attributes as OpenSeaNftAttribute[] | undefined)\n .filter((v): v is OpenSeaNftAttribute[] => v !== undefined)\n .map((attributes) => {\n return Object.fromEntries(attributes.map((attribute) => [attribute.trait_type, attribute.value]))\n })\n const distribution = calculateAllPropertiesDistribution(traits)\n const n = nfts.length\n const attributes = Object.fromEntries(\n Object.entries(distribution)\n .filter((v): v is TraitDistributionEntry => v[1] !== undefined)\n .map(([trait, entries]) => {\n const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0)\n const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n)\n const values = Object.fromEntries(\n Object.entries(entries).map(([value, traitValueCount]) => {\n const { p } = calculateBinomialParamsFromProbability(n, traitValueCount / n)\n const metrics: NftTraitMetrics = { binomial: { p }, count: traitValueCount }\n return [value, metrics]\n }),\n )\n return [trait, { metrics: { binomial: { p }, count: traitCount }, values }]\n }),\n )\n return { metadata: { attributes } }\n}\n","import { Auth, SDK } from '@infura/sdk'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionCount = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n): Promise<number> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const opts: ContractAddressOptions = { contractAddress }\n const { total } = await sdk.api.getNFTsForCollection(opts)\n return total\n}\n","/**\n * These contracts are not evaluable for some\n * reason (too large, nonsensical, etc.)\n */\nexport const nonEvaluableContractAddresses = [\n // ENS\n '0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',\n].map((address) => address.toUpperCase())\n","import { Auth, SDK } from '@infura/sdk'\nimport { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionMetadata = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n): Promise<Omit<NftCollectionMetadata, 'total'>> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const opts: ContractAddressOptions = { contractAddress }\n const { name, symbol, tokenType } = await sdk.api.getContractMetadata(opts)\n const type = toTokenType(tokenType)\n return { address: contractAddress, chainId, name, symbol, type }\n}\n","import { Auth, SDK } from '@infura/sdk'\nimport { NftInfo, NftInfoFields, NftSchema, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionNfts = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n maxNfts = 100,\n): Promise<NftInfo[]> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const nfts: NftInfoFields[] = []\n let cursor: string | undefined = undefined\n do {\n const opts: ContractAddressOptions = { contractAddress, cursor }\n const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTsForCollection(opts)\n const batch: NftInfoFields[] = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {\n const { contract: address, type: tokenType, ...rest } = asset\n const type = toTokenType(tokenType)\n return { address, chainId, type, ...rest }\n })\n nfts.push(...batch)\n cursor = nextCursor\n if (nfts.length >= total || !cursor) break\n } while (nfts.length < maxNfts)\n return nfts.map((nft) => {\n return { ...nft, schema: NftSchema }\n })\n}\n"],"mappings":"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","names":["import_crypto_nft_payload_plugin","attributes","p","import_sdk","import_sdk","import_crypto_nft_payload_plugin"]}
@@ -1,9 +1,194 @@
1
- import { CryptoNftCollectionWitnessPlugin } from "./Plugin";
2
- export * from "./lib";
3
- export * from "./Witness";
1
+ // src/Plugin.ts
2
+ import { NftSchema as NftSchema2 } from "@xyo-network/crypto-nft-payload-plugin";
3
+ import { PayloadSetSchema } from "@xyo-network/payload-model";
4
+ import { createPayloadSetWitnessPlugin } from "@xyo-network/payloadset-plugin";
5
+
6
+ // src/Witness.ts
7
+ import { assertEx } from "@xylabs/assert";
8
+ import { PayloadHasher } from "@xyo-network/core";
9
+ import {
10
+ isNftCollectionWitnessQuery,
11
+ NftCollectionSchema,
12
+ NftCollectionWitnessConfigSchema
13
+ } from "@xyo-network/crypto-nft-collection-payload-plugin";
14
+ import { AbstractWitness } from "@xyo-network/witness";
15
+
16
+ // src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
17
+ var calculateAllPropertiesDistribution = (array) => {
18
+ const distribution = {};
19
+ array.forEach((item) => {
20
+ for (const property in item) {
21
+ if (Object.prototype.hasOwnProperty.call(item, property)) {
22
+ const value = item[property];
23
+ if (value !== void 0 && value !== null) {
24
+ const valueString = value.toString();
25
+ if (!distribution[property]) {
26
+ distribution[property] = { [valueString]: 1 };
27
+ } else if (!distribution[property][valueString]) {
28
+ ;
29
+ distribution[property][valueString] = 1;
30
+ } else {
31
+ ;
32
+ distribution[property][valueString] += 1;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ });
38
+ return distribution;
39
+ };
40
+
41
+ // src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts
42
+ var calculateBinomialParamsFromProbability = (n, p) => {
43
+ const mean = n * p;
44
+ const variance = n * p * (1 - p);
45
+ const stdDev = Math.sqrt(variance);
46
+ return { mean, p, stdDev, variance };
47
+ };
48
+
49
+ // src/lib/collectionMetrics/getNftCollectionMetrics.ts
50
+ var getNftCollectionMetrics = (nfts) => {
51
+ const traits = nfts.map((nft) => {
52
+ var _a;
53
+ return (_a = nft == null ? void 0 : nft.metadata) == null ? void 0 : _a.attributes;
54
+ }).filter((v) => v !== void 0).map((attributes2) => {
55
+ return Object.fromEntries(attributes2.map((attribute) => [attribute.trait_type, attribute.value]));
56
+ });
57
+ const distribution = calculateAllPropertiesDistribution(traits);
58
+ const n = nfts.length;
59
+ const attributes = Object.fromEntries(
60
+ Object.entries(distribution).filter((v) => v[1] !== void 0).map(([trait, entries]) => {
61
+ const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0);
62
+ const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n);
63
+ const values = Object.fromEntries(
64
+ Object.entries(entries).map(([value, traitValueCount]) => {
65
+ const { p: p2 } = calculateBinomialParamsFromProbability(n, traitValueCount / n);
66
+ const metrics = { binomial: { p: p2 }, count: traitValueCount };
67
+ return [value, metrics];
68
+ })
69
+ );
70
+ return [trait, { metrics: { binomial: { p }, count: traitCount }, values }];
71
+ })
72
+ );
73
+ return { metadata: { attributes } };
74
+ };
75
+
76
+ // src/lib/getNftCollectionCount.ts
77
+ import { Auth, SDK } from "@infura/sdk";
78
+
79
+ // src/lib/nonEvaluableContractAddresses.ts
80
+ var nonEvaluableContractAddresses = [
81
+ // ENS
82
+ "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72"
83
+ ].map((address) => address.toUpperCase());
84
+
85
+ // src/lib/getNftCollectionCount.ts
86
+ var getNftCollectionCount = async (contractAddress, chainId, privateKey) => {
87
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
88
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
89
+ }
90
+ const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
91
+ const opts = { contractAddress };
92
+ const { total } = await sdk.api.getNFTsForCollection(opts);
93
+ return total;
94
+ };
95
+
96
+ // src/lib/getNftCollectionMetadata.ts
97
+ import { Auth as Auth2, SDK as SDK2 } from "@infura/sdk";
98
+ import { toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
99
+ var getNftCollectionMetadata = async (contractAddress, chainId, privateKey) => {
100
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
101
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
102
+ }
103
+ const sdk = new SDK2(new Auth2({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
104
+ const opts = { contractAddress };
105
+ const { name, symbol, tokenType } = await sdk.api.getContractMetadata(opts);
106
+ const type = toTokenType(tokenType);
107
+ return { address: contractAddress, chainId, name, symbol, type };
108
+ };
109
+
110
+ // src/lib/getNftCollectionNfts.ts
111
+ import { Auth as Auth3, SDK as SDK3 } from "@infura/sdk";
112
+ import { NftSchema, toTokenType as toTokenType2 } from "@xyo-network/crypto-nft-payload-plugin";
113
+ var getNftCollectionNfts = async (contractAddress, chainId, privateKey, maxNfts = 100) => {
114
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
115
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
116
+ }
117
+ const sdk = new SDK3(new Auth3({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
118
+ const nfts = [];
119
+ let cursor = void 0;
120
+ do {
121
+ const opts = { contractAddress, cursor };
122
+ const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTsForCollection(opts);
123
+ const batch = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {
124
+ const { contract: address, type: tokenType, ...rest } = asset;
125
+ const type = toTokenType2(tokenType);
126
+ return { address, chainId, type, ...rest };
127
+ });
128
+ nfts.push(...batch);
129
+ cursor = nextCursor;
130
+ if (nfts.length >= total || !cursor)
131
+ break;
132
+ } while (nfts.length < maxNfts);
133
+ return nfts.map((nft) => {
134
+ return { ...nft, schema: NftSchema };
135
+ });
136
+ };
137
+
138
+ // src/Witness.ts
139
+ var defaultMaxNfts = 100;
140
+ var NoOp = Promise.resolve();
141
+ var CryptoNftCollectionWitness = class extends AbstractWitness {
142
+ static configSchemas = [NftCollectionWitnessConfigSchema];
143
+ async observeHandler(payloads) {
144
+ await this.started("throw");
145
+ const queries = (payloads == null ? void 0 : payloads.filter(isNftCollectionWitnessQuery)) ?? [];
146
+ const observations = await Promise.all(
147
+ queries.map(async (query) => {
148
+ const address = assertEx((query == null ? void 0 : query.address) || this.config.address, "params.address is required");
149
+ const chainId = assertEx((query == null ? void 0 : query.chainId) || this.config.chainId, "params.chainId is required");
150
+ const maxNfts = (query == null ? void 0 : query.maxNfts) || defaultMaxNfts;
151
+ const [info, total, nfts, archivist] = await Promise.all([
152
+ getNftCollectionMetadata(address, chainId, this.account.private.hex),
153
+ getNftCollectionCount(address, chainId, this.account.private.hex),
154
+ getNftCollectionNfts(address, chainId, this.account.private.hex, maxNfts),
155
+ this.writeArchivist()
156
+ ]);
157
+ const metrics = getNftCollectionMetrics(nfts);
158
+ const [sources] = await Promise.all([
159
+ // Hash all the payloads
160
+ Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),
161
+ // Insert them into the archivist if we have one
162
+ archivist ? archivist.insert(nfts) : NoOp
163
+ ]);
164
+ const payload = { ...info, metrics, schema: NftCollectionSchema, sources, total };
165
+ return payload;
166
+ })
167
+ );
168
+ return observations.flat();
169
+ }
170
+ };
171
+
172
+ // src/Plugin.ts
173
+ var CryptoNftCollectionWitnessPlugin = () => createPayloadSetWitnessPlugin(
174
+ { required: { [NftSchema2]: 1 }, schema: PayloadSetSchema },
175
+ {
176
+ witness: async (params) => {
177
+ const result = await CryptoNftCollectionWitness.create(params);
178
+ return result;
179
+ }
180
+ }
181
+ );
182
+
183
+ // src/index.ts
4
184
  var src_default = CryptoNftCollectionWitnessPlugin;
5
185
  export {
186
+ CryptoNftCollectionWitness,
6
187
  CryptoNftCollectionWitnessPlugin,
7
- src_default as default
188
+ src_default as default,
189
+ getNftCollectionCount,
190
+ getNftCollectionMetadata,
191
+ getNftCollectionMetrics,
192
+ getNftCollectionNfts
8
193
  };
9
194
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n"],"mappings":"AAAA,SAAS,wCAAwC;AAEjD,cAAc;AACd,cAAc;AAKd,IAAO,cAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts","../../src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts","../../src/lib/collectionMetrics/getNftCollectionMetrics.ts","../../src/lib/getNftCollectionCount.ts","../../src/lib/nonEvaluableContractAddresses.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getNftCollectionNfts.ts","../../src/index.ts"],"sourcesContent":["import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoNftCollectionWitness } from './Witness'\n\nexport const CryptoNftCollectionWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoNftCollectionWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoNftCollectionWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { PayloadHasher } from '@xyo-network/core'\nimport {\n isNftCollectionWitnessQuery,\n NftCollectionInfo,\n NftCollectionSchema,\n NftCollectionWitnessConfig,\n NftCollectionWitnessConfigSchema,\n} from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module'\nimport { Payload } from '@xyo-network/payload-model'\nimport { AbstractWitness, WitnessParams } from '@xyo-network/witness'\n\nimport { getNftCollectionCount, getNftCollectionMetadata, getNftCollectionMetrics, getNftCollectionNfts } from './lib'\n\nexport type CryptoNftCollectionWitnessParams = WitnessParams<AnyConfigSchema<NftCollectionWitnessConfig>>\n\nconst defaultMaxNfts = 100\n\n/**\n * A \"no operation\" Promise to be used\n * when no action is desired but a Promise\n * is required to be returned\n */\nconst NoOp = Promise.resolve()\n\nexport class CryptoNftCollectionWitness<\n TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams,\n> extends AbstractWitness<TParams> {\n static override configSchemas = [NftCollectionWitnessConfigSchema]\n\n protected override async observeHandler(payloads?: Payload[]): Promise<Payload[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftCollectionWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map<Promise<NftCollectionInfo>>(async (query) => {\n const address = assertEx(query?.address || this.config.address, 'params.address is required')\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n const [info, total, nfts, archivist] = await Promise.all([\n getNftCollectionMetadata(address, chainId, this.account.private.hex),\n getNftCollectionCount(address, chainId, this.account.private.hex),\n getNftCollectionNfts(address, chainId, this.account.private.hex, maxNfts),\n this.writeArchivist(),\n ])\n const metrics = getNftCollectionMetrics(nfts)\n const [sources] = await Promise.all([\n // Hash all the payloads\n Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),\n // Insert them into the archivist if we have one\n archivist ? archivist.insert(nfts) : NoOp,\n ])\n const payload: NftCollectionInfo = { ...info, metrics, schema: NftCollectionSchema, sources, total }\n return payload\n }),\n )\n return observations.flat()\n }\n}\n","import { Distribution } from './distribution'\n\nexport const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {\n const distribution: Distribution<T> = {}\n\n array.forEach((item) => {\n for (const property in item) {\n if (Object.prototype.hasOwnProperty.call(item, property)) {\n const value = item[property as keyof T]\n if (value !== undefined && value !== null) {\n const valueString = value.toString()\n if (!distribution[property]) {\n distribution[property] = { [valueString]: 1 }\n } else if (!distribution[property]![valueString]) {\n ;(distribution[property] as Record<string, number>)[valueString] = 1\n } else {\n ;(distribution[property] as Record<string, number>)[valueString] += 1\n }\n }\n }\n }\n })\n\n return distribution\n}\n","import { BinomialDistributionParameters } from '@xyo-network/crypto-nft-collection-payload-plugin'\n\n/**\n * Calculates the parameters of a binomial distribution given the number of trials and success probability\n * @param n Number of trials\n * @param p Success probability\n * @returns The binomial distribution parameters\n */\nexport const calculateBinomialParamsFromProbability = (n: number, p: number): BinomialDistributionParameters => {\n // Mean (µ)\n const mean = n * p\n\n // Variance (σ^2)\n const variance = n * p * (1 - p)\n\n // Standard Deviation (σ)\n const stdDev = Math.sqrt(variance)\n\n return { mean, p, stdDev, variance }\n}\n","import { NftCollectionMetrics, NftTraitMetrics } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { NftInfoFields, OpenSeaNftAttribute } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { calculateAllPropertiesDistribution, calculateBinomialParamsFromProbability } from './lib'\n\ntype TraitDistributionEntry = [string, { [key: string]: number }]\n\nexport const getNftCollectionMetrics = (nfts: NftInfoFields[]): NftCollectionMetrics => {\n const traits = nfts\n .map((nft) => nft?.metadata?.attributes as OpenSeaNftAttribute[] | undefined)\n .filter((v): v is OpenSeaNftAttribute[] => v !== undefined)\n .map((attributes) => {\n return Object.fromEntries(attributes.map((attribute) => [attribute.trait_type, attribute.value]))\n })\n const distribution = calculateAllPropertiesDistribution(traits)\n const n = nfts.length\n const attributes = Object.fromEntries(\n Object.entries(distribution)\n .filter((v): v is TraitDistributionEntry => v[1] !== undefined)\n .map(([trait, entries]) => {\n const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0)\n const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n)\n const values = Object.fromEntries(\n Object.entries(entries).map(([value, traitValueCount]) => {\n const { p } = calculateBinomialParamsFromProbability(n, traitValueCount / n)\n const metrics: NftTraitMetrics = { binomial: { p }, count: traitValueCount }\n return [value, metrics]\n }),\n )\n return [trait, { metrics: { binomial: { p }, count: traitCount }, values }]\n }),\n )\n return { metadata: { attributes } }\n}\n","import { Auth, SDK } from '@infura/sdk'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionCount = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n): Promise<number> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const opts: ContractAddressOptions = { contractAddress }\n const { total } = await sdk.api.getNFTsForCollection(opts)\n return total\n}\n","/**\n * These contracts are not evaluable for some\n * reason (too large, nonsensical, etc.)\n */\nexport const nonEvaluableContractAddresses = [\n // ENS\n '0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',\n].map((address) => address.toUpperCase())\n","import { Auth, SDK } from '@infura/sdk'\nimport { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionMetadata = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n): Promise<Omit<NftCollectionMetadata, 'total'>> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const opts: ContractAddressOptions = { contractAddress }\n const { name, symbol, tokenType } = await sdk.api.getContractMetadata(opts)\n const type = toTokenType(tokenType)\n return { address: contractAddress, chainId, name, symbol, type }\n}\n","import { Auth, SDK } from '@infura/sdk'\nimport { NftInfo, NftInfoFields, NftSchema, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\n\nimport { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses'\n\ntype ContractAddressOptions = {\n contractAddress: string\n cursor?: string\n}\n\nexport const getNftCollectionNfts = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n chainId: number,\n // /**\n // * The ethers provider to use to search for NFTs\n // */\n // provider: ExternalProvider | JsonRpcFetchFunc,\n /**\n * The private key of the wallet to use to search for NFTs\n */\n privateKey: string,\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n maxNfts = 100,\n): Promise<NftInfo[]> => {\n if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {\n throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`)\n }\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const nfts: NftInfoFields[] = []\n let cursor: string | undefined = undefined\n do {\n const opts: ContractAddressOptions = { contractAddress, cursor }\n const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTsForCollection(opts)\n const batch: NftInfoFields[] = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {\n const { contract: address, type: tokenType, ...rest } = asset\n const type = toTokenType(tokenType)\n return { address, chainId, type, ...rest }\n })\n nfts.push(...batch)\n cursor = nextCursor\n if (nfts.length >= total || !cursor) break\n } while (nfts.length < maxNfts)\n return nfts.map((nft) => {\n return { ...nft, schema: NftSchema }\n })\n}\n","import { CryptoNftCollectionWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoNftCollectionWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoNftCollectionWitnessPlugin\n"],"mappings":"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","names":["NftSchema","attributes","p","Auth","SDK","SDK","Auth","Auth","SDK","toTokenType","SDK","Auth","toTokenType","NftSchema"]}
@@ -0,0 +1,4 @@
1
+ import { NftCollectionMetrics } from '@xyo-network/crypto-nft-collection-payload-plugin';
2
+ import { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin';
3
+ export declare const getNftCollectionMetrics: (nfts: NftInfoFields[]) => NftCollectionMetrics;
4
+ //# sourceMappingURL=getNftCollectionMetrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNftCollectionMetrics.d.ts","sourceRoot":"","sources":["../../../../src/lib/collectionMetrics/getNftCollectionMetrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,mDAAmD,CAAA;AACzG,OAAO,EAAE,aAAa,EAAuB,MAAM,wCAAwC,CAAA;AAM3F,eAAO,MAAM,uBAAuB,SAAU,aAAa,EAAE,KAAG,oBA0B/D,CAAA"}
@@ -16,25 +16,64 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/collectionMetrics/getNftCollectionMetrics.ts
19
21
  var getNftCollectionMetrics_exports = {};
20
22
  __export(getNftCollectionMetrics_exports, {
21
23
  getNftCollectionMetrics: () => getNftCollectionMetrics
22
24
  });
23
25
  module.exports = __toCommonJS(getNftCollectionMetrics_exports);
24
- var import_lib = require("./lib");
25
- const getNftCollectionMetrics = (nfts) => {
26
- const traits = nfts.map((nft) => nft?.metadata?.attributes).filter((v) => v !== void 0).map((attributes2) => {
26
+
27
+ // src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts
28
+ var calculateAllPropertiesDistribution = (array) => {
29
+ const distribution = {};
30
+ array.forEach((item) => {
31
+ for (const property in item) {
32
+ if (Object.prototype.hasOwnProperty.call(item, property)) {
33
+ const value = item[property];
34
+ if (value !== void 0 && value !== null) {
35
+ const valueString = value.toString();
36
+ if (!distribution[property]) {
37
+ distribution[property] = { [valueString]: 1 };
38
+ } else if (!distribution[property][valueString]) {
39
+ ;
40
+ distribution[property][valueString] = 1;
41
+ } else {
42
+ ;
43
+ distribution[property][valueString] += 1;
44
+ }
45
+ }
46
+ }
47
+ }
48
+ });
49
+ return distribution;
50
+ };
51
+
52
+ // src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts
53
+ var calculateBinomialParamsFromProbability = (n, p) => {
54
+ const mean = n * p;
55
+ const variance = n * p * (1 - p);
56
+ const stdDev = Math.sqrt(variance);
57
+ return { mean, p, stdDev, variance };
58
+ };
59
+
60
+ // src/lib/collectionMetrics/getNftCollectionMetrics.ts
61
+ var getNftCollectionMetrics = (nfts) => {
62
+ const traits = nfts.map((nft) => {
63
+ var _a;
64
+ return (_a = nft == null ? void 0 : nft.metadata) == null ? void 0 : _a.attributes;
65
+ }).filter((v) => v !== void 0).map((attributes2) => {
27
66
  return Object.fromEntries(attributes2.map((attribute) => [attribute.trait_type, attribute.value]));
28
67
  });
29
- const distribution = (0, import_lib.calculateAllPropertiesDistribution)(traits);
68
+ const distribution = calculateAllPropertiesDistribution(traits);
30
69
  const n = nfts.length;
31
70
  const attributes = Object.fromEntries(
32
71
  Object.entries(distribution).filter((v) => v[1] !== void 0).map(([trait, entries]) => {
33
72
  const traitCount = Object.values(entries).reduce((prev, curr) => prev + curr, 0);
34
- const { p } = (0, import_lib.calculateBinomialParamsFromProbability)(nfts.length, traitCount / n);
73
+ const { p } = calculateBinomialParamsFromProbability(nfts.length, traitCount / n);
35
74
  const values = Object.fromEntries(
36
75
  Object.entries(entries).map(([value, traitValueCount]) => {
37
- const { p: p2 } = (0, import_lib.calculateBinomialParamsFromProbability)(n, traitValueCount / n);
76
+ const { p: p2 } = calculateBinomialParamsFromProbability(n, traitValueCount / n);
38
77
  const metrics = { binomial: { p: p2 }, count: traitValueCount };
39
78
  return [value, metrics];
40
79
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/collectionMetrics/getNftCollectionMetrics.ts"],"sourcesContent":["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"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAA2F;AAIpF,MAAM,0BAA0B,CAAC,SAAgD;AACtF,QAAM,SAAS,KACZ,IAAI,CAAC,QAAQ,KAAK,UAAU,UAA+C,EAC3E,OAAO,CAAC,MAAkC,MAAM,MAAS,EACzD,IAAI,CAACA,gBAAe;AACnB,WAAO,OAAO,YAAYA,YAAW,IAAI,CAAC,cAAc,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,CAAC;AAAA,EAClG,CAAC;AACH,QAAM,mBAAe,+CAAmC,MAAM;AAC9D,QAAM,IAAI,KAAK;AACf,QAAM,aAAa,OAAO;AAAA,IACxB,OAAO,QAAQ,YAAY,EACxB,OAAO,CAAC,MAAmC,EAAE,CAAC,MAAM,MAAS,EAC7D,IAAI,CAAC,CAAC,OAAO,OAAO,MAAM;AACzB,YAAM,aAAa,OAAO,OAAO,OAAO,EAAE,OAAO,CAAC,MAAM,SAAS,OAAO,MAAM,CAAC;AAC/E,YAAM,EAAE,EAAE,QAAI,mDAAuC,KAAK,QAAQ,aAAa,CAAC;AAChF,YAAM,SAAS,OAAO;AAAA,QACpB,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,eAAe,MAAM;AACxD,gBAAM,EAAE,GAAAC,GAAE,QAAI,mDAAuC,GAAG,kBAAkB,CAAC;AAC3E,gBAAM,UAA2B,EAAE,UAAU,EAAE,GAAAA,GAAE,GAAG,OAAO,gBAAgB;AAC3E,iBAAO,CAAC,OAAO,OAAO;AAAA,QACxB,CAAC;AAAA,MACH;AACA,aAAO,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,GAAG,OAAO,WAAW,GAAG,OAAO,CAAC;AAAA,IAC5E,CAAC;AAAA,EACL;AACA,SAAO,EAAE,UAAU,EAAE,WAAW,EAAE;AACpC;","names":["attributes","p"]}
1
+ {"version":3,"sources":["../../../../src/lib/collectionMetrics/getNftCollectionMetrics.ts","../../../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts","../../../../src/lib/collectionMetrics/lib/probabilityDistributions/binomial/calculateBinomialParamsFromProbability.ts"],"sourcesContent":["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 { 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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,qCAAqC,CAAI,UAAgC;AACpF,QAAM,eAAgC,CAAC;AAEvC,QAAM,QAAQ,CAAC,SAAS;AACtB,eAAW,YAAY,MAAM;AAC3B,UAAI,OAAO,UAAU,eAAe,KAAK,MAAM,QAAQ,GAAG;AACxD,cAAM,QAAQ,KAAK,QAAmB;AACtC,YAAI,UAAU,UAAa,UAAU,MAAM;AACzC,gBAAM,cAAc,MAAM,SAAS;AACnC,cAAI,CAAC,aAAa,QAAQ,GAAG;AAC3B,yBAAa,QAAQ,IAAI,EAAE,CAAC,WAAW,GAAG,EAAE;AAAA,UAC9C,WAAW,CAAC,aAAa,QAAQ,EAAG,WAAW,GAAG;AAChD;AAAC,YAAC,aAAa,QAAQ,EAA6B,WAAW,IAAI;AAAA,UACrE,OAAO;AACL;AAAC,YAAC,aAAa,QAAQ,EAA6B,WAAW,KAAK;AAAA,UACtE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;;;AChBO,IAAM,yCAAyC,CAAC,GAAW,MAA8C;AAE9G,QAAM,OAAO,IAAI;AAGjB,QAAM,WAAW,IAAI,KAAK,IAAI;AAG9B,QAAM,SAAS,KAAK,KAAK,QAAQ;AAEjC,SAAO,EAAE,MAAM,GAAG,QAAQ,SAAS;AACrC;;;AFZO,IAAM,0BAA0B,CAAC,SAAgD;AACtF,QAAM,SAAS,KACZ,IAAI,CAAC,QAAK;AATf;AASkB,4CAAK,aAAL,mBAAe;AAAA,GAA+C,EAC3E,OAAO,CAAC,MAAkC,MAAM,MAAS,EACzD,IAAI,CAACA,gBAAe;AACnB,WAAO,OAAO,YAAYA,YAAW,IAAI,CAAC,cAAc,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,CAAC;AAAA,EAClG,CAAC;AACH,QAAM,eAAe,mCAAmC,MAAM;AAC9D,QAAM,IAAI,KAAK;AACf,QAAM,aAAa,OAAO;AAAA,IACxB,OAAO,QAAQ,YAAY,EACxB,OAAO,CAAC,MAAmC,EAAE,CAAC,MAAM,MAAS,EAC7D,IAAI,CAAC,CAAC,OAAO,OAAO,MAAM;AACzB,YAAM,aAAa,OAAO,OAAO,OAAO,EAAE,OAAO,CAAC,MAAM,SAAS,OAAO,MAAM,CAAC;AAC/E,YAAM,EAAE,EAAE,IAAI,uCAAuC,KAAK,QAAQ,aAAa,CAAC;AAChF,YAAM,SAAS,OAAO;AAAA,QACpB,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,eAAe,MAAM;AACxD,gBAAM,EAAE,GAAAC,GAAE,IAAI,uCAAuC,GAAG,kBAAkB,CAAC;AAC3E,gBAAM,UAA2B,EAAE,UAAU,EAAE,GAAAA,GAAE,GAAG,OAAO,gBAAgB;AAC3E,iBAAO,CAAC,OAAO,OAAO;AAAA,QACxB,CAAC;AAAA,MACH;AACA,aAAO,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,GAAG,OAAO,WAAW,GAAG,OAAO,CAAC;AAAA,IAC5E,CAAC;AAAA,EACL;AACA,SAAO,EAAE,UAAU,EAAE,WAAW,EAAE;AACpC;","names":["attributes","p"]}