@xyo-network/crypto-nft-collection-witness-plugin 2.70.5 → 2.70.6

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 (85) hide show
  1. package/dist/cjs/Witness.js +23 -2
  2. package/dist/cjs/Witness.js.map +1 -1
  3. package/dist/cjs/lib/collectionMetrics/getNftCollectionMetrics.js +21 -0
  4. package/dist/cjs/lib/collectionMetrics/getNftCollectionMetrics.js.map +1 -0
  5. package/dist/cjs/lib/collectionMetrics/index.js +5 -0
  6. package/dist/cjs/lib/collectionMetrics/index.js.map +1 -0
  7. package/dist/cjs/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js +30 -0
  8. package/dist/cjs/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js.map +1 -0
  9. package/dist/cjs/lib/collectionMetrics/lib/calculatePropertyDistribution.js +26 -0
  10. package/dist/cjs/lib/collectionMetrics/lib/calculatePropertyDistribution.js.map +1 -0
  11. package/dist/cjs/lib/collectionMetrics/lib/distribution.js +3 -0
  12. package/dist/cjs/lib/collectionMetrics/lib/distribution.js.map +1 -0
  13. package/dist/cjs/lib/collectionMetrics/lib/index.js +6 -0
  14. package/dist/cjs/lib/collectionMetrics/lib/index.js.map +1 -0
  15. package/dist/cjs/lib/getNftCollectionInfo.js +6 -32
  16. package/dist/cjs/lib/getNftCollectionInfo.js.map +1 -1
  17. package/dist/cjs/lib/getNftCollectionNfts.js +51 -0
  18. package/dist/cjs/lib/getNftCollectionNfts.js.map +1 -0
  19. package/dist/cjs/lib/getNftCollectionTotalNfts.js +33 -0
  20. package/dist/cjs/lib/getNftCollectionTotalNfts.js.map +1 -0
  21. package/dist/cjs/lib/index.js +3 -0
  22. package/dist/cjs/lib/index.js.map +1 -1
  23. package/dist/cjs/lib/nonEvaluableContractAddresses.js +12 -0
  24. package/dist/cjs/lib/nonEvaluableContractAddresses.js.map +1 -0
  25. package/dist/docs.json +2167 -1627
  26. package/dist/esm/Witness.js +25 -4
  27. package/dist/esm/Witness.js.map +1 -1
  28. package/dist/esm/lib/collectionMetrics/getNftCollectionMetrics.js +17 -0
  29. package/dist/esm/lib/collectionMetrics/getNftCollectionMetrics.js.map +1 -0
  30. package/dist/esm/lib/collectionMetrics/index.js +2 -0
  31. package/dist/esm/lib/collectionMetrics/index.js.map +1 -0
  32. package/dist/esm/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js +26 -0
  33. package/dist/esm/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.js.map +1 -0
  34. package/dist/esm/lib/collectionMetrics/lib/calculatePropertyDistribution.js +22 -0
  35. package/dist/esm/lib/collectionMetrics/lib/calculatePropertyDistribution.js.map +1 -0
  36. package/dist/esm/lib/collectionMetrics/lib/distribution.js +2 -0
  37. package/dist/esm/lib/collectionMetrics/lib/distribution.js.map +1 -0
  38. package/dist/esm/lib/collectionMetrics/lib/index.js +3 -0
  39. package/dist/esm/lib/collectionMetrics/lib/index.js.map +1 -0
  40. package/dist/esm/lib/getNftCollectionInfo.js +4 -30
  41. package/dist/esm/lib/getNftCollectionInfo.js.map +1 -1
  42. package/dist/esm/lib/getNftCollectionNfts.js +46 -0
  43. package/dist/esm/lib/getNftCollectionNfts.js.map +1 -0
  44. package/dist/esm/lib/getNftCollectionTotalNfts.js +28 -0
  45. package/dist/esm/lib/getNftCollectionTotalNfts.js.map +1 -0
  46. package/dist/esm/lib/index.js +3 -0
  47. package/dist/esm/lib/index.js.map +1 -1
  48. package/dist/esm/lib/nonEvaluableContractAddresses.js +9 -0
  49. package/dist/esm/lib/nonEvaluableContractAddresses.js.map +1 -0
  50. package/dist/types/Witness.d.ts.map +1 -1
  51. package/dist/types/lib/collectionMetrics/getNftCollectionMetrics.d.ts +13 -0
  52. package/dist/types/lib/collectionMetrics/getNftCollectionMetrics.d.ts.map +1 -0
  53. package/dist/types/lib/collectionMetrics/index.d.ts +2 -0
  54. package/dist/types/lib/collectionMetrics/index.d.ts.map +1 -0
  55. package/dist/types/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.ts +3 -0
  56. package/dist/types/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.d.ts.map +1 -0
  57. package/dist/types/lib/collectionMetrics/lib/calculatePropertyDistribution.d.ts +3 -0
  58. package/dist/types/lib/collectionMetrics/lib/calculatePropertyDistribution.d.ts.map +1 -0
  59. package/dist/types/lib/collectionMetrics/lib/distribution.d.ts +6 -0
  60. package/dist/types/lib/collectionMetrics/lib/distribution.d.ts.map +1 -0
  61. package/dist/types/lib/collectionMetrics/lib/index.d.ts +3 -0
  62. package/dist/types/lib/collectionMetrics/lib/index.d.ts.map +1 -0
  63. package/dist/types/lib/getNftCollectionInfo.d.ts +2 -7
  64. package/dist/types/lib/getNftCollectionInfo.d.ts.map +1 -1
  65. package/dist/types/lib/getNftCollectionNfts.d.ts +3 -0
  66. package/dist/types/lib/getNftCollectionNfts.d.ts.map +1 -0
  67. package/dist/types/lib/getNftCollectionTotalNfts.d.ts +2 -0
  68. package/dist/types/lib/getNftCollectionTotalNfts.d.ts.map +1 -0
  69. package/dist/types/lib/index.d.ts +3 -0
  70. package/dist/types/lib/index.d.ts.map +1 -1
  71. package/dist/types/lib/nonEvaluableContractAddresses.d.ts +6 -0
  72. package/dist/types/lib/nonEvaluableContractAddresses.d.ts.map +1 -0
  73. package/package.json +8 -7
  74. package/src/Witness.ts +29 -4
  75. package/src/lib/collectionMetrics/getNftCollectionMetrics.ts +29 -0
  76. package/src/lib/collectionMetrics/index.ts +1 -0
  77. package/src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts +25 -0
  78. package/src/lib/collectionMetrics/lib/calculatePropertyDistribution.ts +19 -0
  79. package/src/lib/collectionMetrics/lib/distribution.ts +3 -0
  80. package/src/lib/collectionMetrics/lib/index.ts +2 -0
  81. package/src/lib/getNftCollectionInfo.ts +5 -32
  82. package/src/lib/getNftCollectionNfts.ts +52 -0
  83. package/src/lib/getNftCollectionTotalNfts.ts +35 -0
  84. package/src/lib/index.ts +3 -0
  85. package/src/lib/nonEvaluableContractAddresses.ts +8 -0
@@ -1,7 +1,15 @@
1
1
  import { assertEx } from '@xylabs/assert';
2
- import { isNftCollectionWitnessQueryPayload, NftCollectionWitnessConfigSchema, } from '@xyo-network/crypto-nft-collection-payload-plugin';
2
+ import { PayloadHasher } from '@xyo-network/core';
3
+ import { isNftCollectionWitnessQueryPayload, NftCollectionSchema, NftCollectionWitnessConfigSchema, } from '@xyo-network/crypto-nft-collection-payload-plugin';
3
4
  import { AbstractWitness } from '@xyo-network/witness';
4
- import { getNftCollectionInfo } from './lib';
5
+ import { getNftCollectionInfo, getNftCollectionMetrics, getNftCollectionNfts, getNftCollectionTotalNfts } from './lib';
6
+ const defaultMaxNftSampleSize = 100;
7
+ /**
8
+ * A "no operation" Promise to be used
9
+ * when no action is desired but a Promise
10
+ * is required to be returned
11
+ */
12
+ const NoOp = Promise.resolve();
5
13
  export class CryptoNftCollectionWitness extends AbstractWitness {
6
14
  static configSchemas = [NftCollectionWitnessConfigSchema];
7
15
  async observeHandler(payloads) {
@@ -10,8 +18,21 @@ export class CryptoNftCollectionWitness extends AbstractWitness {
10
18
  const observations = await Promise.all(queries.map(async (query) => {
11
19
  const address = assertEx(query?.address || this.config.address, 'params.address is required');
12
20
  const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required');
13
- const observation = await getNftCollectionInfo(address, chainId, this.account.private.hex);
14
- return observation;
21
+ const maxNftSampleSize = query?.maxNftSampleSize || defaultMaxNftSampleSize;
22
+ const [info, total, nfts, archivist] = await Promise.all([
23
+ getNftCollectionInfo(address, chainId, this.account.private.hex),
24
+ getNftCollectionTotalNfts(address, chainId, this.account.private.hex),
25
+ getNftCollectionNfts(address, chainId, this.account.private.hex, maxNftSampleSize),
26
+ this.writeArchivist(),
27
+ ]);
28
+ const distribution = getNftCollectionMetrics(nfts);
29
+ const [sources] = await Promise.all([
30
+ // Hash all the payloads
31
+ Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),
32
+ // Insert them into the archivist if we have one
33
+ archivist ? archivist.insert(nfts) : NoOp,
34
+ ]);
35
+ return { ...info, ...distribution, schema: NftCollectionSchema, sources, total };
15
36
  }));
16
37
  return observations.flat();
17
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Witness.js","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EACL,kCAAkC,EAElC,gCAAgC,GACjC,MAAM,mDAAmD,CAAA;AAG1D,OAAO,EAAE,eAAe,EAAiB,MAAM,sBAAsB,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAI5C,MAAM,OAAO,0BAEX,SAAQ,eAAwB;IAChC,MAAM,CAAU,aAAa,GAAG,CAAC,gCAAgC,CAAC,CAAA;IAE/C,KAAK,CAAC,cAAc,CAAC,QAAoB;QAC1D,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC3B,MAAM,OAAO,GAAG,QAAQ,EAAE,MAAM,CAAC,kCAAkC,CAAC,IAAI,EAAE,CAAA;QAC1E,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC,CAAA;YAC7F,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC,CAAA;YAC7F,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC1F,OAAO,WAAW,CAAA;QACpB,CAAC,CAAC,CACH,CAAA;QACD,OAAO,YAAY,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC"}
1
+ {"version":3,"file":"Witness.js","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EACL,kCAAkC,EAElC,mBAAmB,EAEnB,gCAAgC,GACjC,MAAM,mDAAmD,CAAA;AAG1D,OAAO,EAAE,eAAe,EAAiB,MAAM,sBAAsB,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,OAAO,CAAA;AAItH,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAEnC;;;;GAIG;AACH,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;AAE9B,MAAM,OAAO,0BAEX,SAAQ,eAAwB;IAChC,MAAM,CAAU,aAAa,GAAG,CAAC,gCAAgC,CAAC,CAAA;IAE/C,KAAK,CAAC,cAAc,CAAC,QAAoB;QAC1D,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC3B,MAAM,OAAO,GAAG,QAAQ,EAAE,MAAM,CAAC,kCAAkC,CAAC,IAAI,EAAE,CAAA;QAC1E,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,OAAO,CAAC,GAAG,CAAoC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC,CAAA;YAC7F,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC,CAAA;YAC7F,MAAM,gBAAgB,GAAG,KAAK,EAAE,gBAAgB,IAAI,uBAAuB,CAAA;YAC3E,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACvD,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;gBAChE,yBAAyB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;gBACrE,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,gBAAgB,CAAC;gBAClF,IAAI,CAAC,cAAc,EAAE;aACtB,CAAC,CAAA;YACF,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;YAClD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClC,wBAAwB;gBACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC5D,gDAAgD;gBAChD,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;aAC1C,CAAC,CAAA;YACF,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;QAClF,CAAC,CAAC,CACH,CAAA;QACD,OAAO,YAAY,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { calculateAllPropertiesDistribution } from './lib';
2
+ export const getNftCollectionMetrics = (nfts) => {
3
+ const attributes = nfts
4
+ .map((nft) => nft.metadata?.attributes)
5
+ .map((attributes) => {
6
+ return Object.fromEntries(attributes.map((attribute) => [attribute.trait_type, attribute.value]));
7
+ });
8
+ const distribution = calculateAllPropertiesDistribution(attributes);
9
+ return {
10
+ distribution: {
11
+ metadata: {
12
+ attributes: distribution,
13
+ },
14
+ },
15
+ };
16
+ };
17
+ //# sourceMappingURL=getNftCollectionMetrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNftCollectionMetrics.js","sourceRoot":"","sources":["../../../../src/lib/collectionMetrics/getNftCollectionMetrics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kCAAkC,EAAgB,MAAM,OAAO,CAAA;AAYxE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAe,EAAwB,EAAE;IAC/E,MAAM,UAAU,GAAG,IAAI;SACpB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAmC,CAAC;SAC/D,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAClB,OAAO,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACnG,CAAC,CAAC,CAAA;IACJ,MAAM,YAAY,GAAG,kCAAkC,CAAC,UAAU,CAAC,CAAA;IACnE,OAAO;QACL,YAAY,EAAE;YACZ,QAAQ,EAAE;gBACR,UAAU,EAAE,YAAY;aACzB;SACF;KACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './getNftCollectionMetrics';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/collectionMetrics/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,26 @@
1
+ export const calculateAllPropertiesDistribution = (array) => {
2
+ const distribution = {};
3
+ array.forEach((item) => {
4
+ for (const property in item) {
5
+ if (Object.prototype.hasOwnProperty.call(item, property)) {
6
+ const value = item[property];
7
+ if (value !== undefined && value !== null) {
8
+ const valueString = value.toString();
9
+ if (!distribution[property]) {
10
+ distribution[property] = { [valueString]: 1 };
11
+ }
12
+ else if (!distribution[property][valueString]) {
13
+ ;
14
+ distribution[property][valueString] = 1;
15
+ }
16
+ else {
17
+ ;
18
+ distribution[property][valueString] += 1;
19
+ }
20
+ }
21
+ }
22
+ }
23
+ });
24
+ return distribution;
25
+ };
26
+ //# sourceMappingURL=calculateAllPropertiesDistribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculateAllPropertiesDistribution.js","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAI,KAAU,EAAmB,EAAE;IACnF,MAAM,YAAY,GAAoB,EAAE,CAAA;IAExC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE;YAC3B,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;gBACxD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAmB,CAAC,CAAA;gBACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;oBACzC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;oBACpC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE;wBAC3B,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAA;qBAC9C;yBAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAE,CAAC,WAAW,CAAC,EAAE;wBAChD,CAAC;wBAAC,YAAY,CAAC,QAAQ,CAA4B,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;qBACrE;yBAAM;wBACL,CAAC;wBAAC,YAAY,CAAC,QAAQ,CAA4B,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;qBACtE;iBACF;aACF;SACF;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA"}
@@ -0,0 +1,22 @@
1
+ export const calculatePropertyDistribution = (array, property) => {
2
+ const distribution = {};
3
+ array.forEach((item) => {
4
+ const value = item[property];
5
+ if (value !== undefined && value !== null) {
6
+ const valueString = value.toString();
7
+ if (!distribution[property]) {
8
+ distribution[property] = { [valueString]: 1 };
9
+ }
10
+ else if (!distribution[property][valueString]) {
11
+ ;
12
+ distribution[property][valueString] = 1;
13
+ }
14
+ else {
15
+ ;
16
+ distribution[property][valueString] += 1;
17
+ }
18
+ }
19
+ });
20
+ return distribution;
21
+ };
22
+ //# sourceMappingURL=calculatePropertyDistribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculatePropertyDistribution.js","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/calculatePropertyDistribution.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAI,KAAU,EAAE,QAAiB,EAAmB,EAAE;IACjG,MAAM,YAAY,GAAoB,EAAE,CAAA;IACxC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;YACzC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;YACpC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE;gBAC3B,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAA;aAC9C;iBAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAE,CAAC,WAAW,CAAC,EAAE;gBAChD,CAAC;gBAAC,YAAY,CAAC,QAAQ,CAA4B,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;aACrE;iBAAM;gBACL,CAAC;gBAAC,YAAY,CAAC,QAAQ,CAA4B,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;aACtE;SACF;IACH,CAAC,CAAC,CAAA;IACF,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=distribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution.js","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/distribution.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export * from './calculateAllPropertiesDistribution';
2
+ export * from './distribution';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA;AACpD,cAAc,gBAAgB,CAAA"}
@@ -1,13 +1,5 @@
1
1
  import { Auth, SDK } from '@infura/sdk';
2
- import { NftCollectionSchema } from '@xyo-network/crypto-nft-collection-payload-plugin';
3
- /**
4
- * These contracts are not evaluable for some
5
- * reason (too large, nonsensical, etc.)
6
- */
7
- export const nonEvaluableContractAddresses = [
8
- // ENS
9
- '0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',
10
- ].map((address) => address.toUpperCase());
2
+ import { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses';
11
3
  export const getNftCollectionInfo = async (
12
4
  /**
13
5
  * The address of the NFT contract to search for
@@ -24,31 +16,13 @@ chainId,
24
16
  /**
25
17
  * The private key of the wallet to use to search for NFTs
26
18
  */
27
- privateKey,
28
- /**
29
- * The maximum number of NFTs to return. Configurable to prevent
30
- * large wallets from exhausting Infura API credits.
31
- */
32
- maxNftCount = 20000) => {
19
+ privateKey) => {
33
20
  if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
34
21
  throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
35
22
  }
36
- // Instantiate SDK
37
- const sdk = new SDK(new Auth({
38
- chainId,
39
- privateKey,
40
- projectId: process.env.INFURA_PROJECT_ID,
41
- // ipfs: {
42
- // apiKeySecret: process.env.INFURA_IPFS_PROJECT_SECRET,
43
- // projectId: process.env.INFURA_IPFS_PROJECT_ID,
44
- // },
45
- // provider,
46
- // NOTE: rpcUrl is not required if chainId & projectId are provided
47
- // rpcUrl: process.env.EVM_RPC_URL,
48
- secretId: process.env.INFURA_PROJECT_SECRET,
49
- }));
23
+ const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
50
24
  const opts = { contractAddress };
51
25
  const { name, symbol, tokenType } = await sdk.api.getContractMetadata(opts);
52
- return { address: contractAddress, chainId, name, schema: NftCollectionSchema, symbol, tokenType };
26
+ return { address: contractAddress, chainId, name, symbol, tokenType };
53
27
  };
54
28
  //# sourceMappingURL=getNftCollectionInfo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getNftCollectionInfo.js","sourceRoot":"","sources":["../../../src/lib/getNftCollectionInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAA4B,mBAAmB,EAAE,MAAM,mDAAmD,CAAA;AAEjH;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,MAAM;IACN,4CAA4C;CAC7C,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;AAOzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK;AACvC;;GAEG;AACH,eAAuB;AACvB;;GAEG;AACH,OAAe;AACf,MAAM;AACN,mDAAmD;AACnD,MAAM;AACN,iDAAiD;AACjD;;GAEG;AACH,UAAkB;AAClB;;;GAGG;AACH,WAAW,GAAG,KAAK,EACgB,EAAE;IACrC,IAAI,6BAA6B,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,EAAE;QACzE,MAAM,IAAI,KAAK,CAAC,uDAAuD,eAAe,EAAE,CAAC,CAAA;KAC1F;IACD,kBAAkB;IAClB,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,IAAI,IAAI,CAAC;QACP,OAAO;QACP,UAAU;QACV,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QACxC,UAAU;QACV,0DAA0D;QAC1D,mDAAmD;QACnD,KAAK;QACL,YAAY;QACZ,mEAAmE;QACnE,mCAAmC;QACnC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;KAC5C,CAAC,CACH,CAAA;IACD,MAAM,IAAI,GAA2B,EAAE,eAAe,EAAE,CAAA;IACxD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;IAC3E,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AACpG,CAAC,CAAA"}
1
+ {"version":3,"file":"getNftCollectionInfo.js","sourceRoot":"","sources":["../../../src/lib/getNftCollectionInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGvC,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAA;AAO/E,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK;AACvC;;GAEG;AACH,eAAuB;AACvB;;GAEG;AACH,OAAe;AACf,MAAM;AACN,mDAAmD;AACnD,MAAM;AACN,iDAAiD;AACjD;;GAEG;AACH,UAAkB,EACyB,EAAE;IAC7C,IAAI,6BAA6B,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,EAAE;QACzE,MAAM,IAAI,KAAK,CAAC,uDAAuD,eAAe,EAAE,CAAC,CAAA;KAC1F;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAA;IAC7I,MAAM,IAAI,GAA2B,EAAE,eAAe,EAAE,CAAA;IACxD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;IAC3E,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AACvE,CAAC,CAAA"}
@@ -0,0 +1,46 @@
1
+ import { Auth, SDK } from '@infura/sdk';
2
+ import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin';
3
+ import { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses';
4
+ export const getNftCollectionNfts = async (
5
+ /**
6
+ * The address of the NFT contract to search for
7
+ */
8
+ contractAddress,
9
+ /**
10
+ * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on
11
+ */
12
+ chainId,
13
+ // /**
14
+ // * The ethers provider to use to search for NFTs
15
+ // */
16
+ // provider: ExternalProvider | JsonRpcFetchFunc,
17
+ /**
18
+ * The private key of the wallet to use to search for NFTs
19
+ */
20
+ privateKey,
21
+ /**
22
+ * The maximum number of NFTs to return. Configurable to prevent
23
+ * large wallets from exhausting Infura API credits. Ideally a
24
+ * multiple of 100 as that appears to be the default page size.
25
+ */
26
+ maxNftSampleSize = 100) => {
27
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
28
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
29
+ }
30
+ const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
31
+ const nfts = [];
32
+ let cursor = undefined;
33
+ do {
34
+ const opts = { contractAddress, cursor };
35
+ const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTsForCollection(opts);
36
+ const batch = assets.slice(0, Math.min(pageSize, total - nfts.length));
37
+ nfts.push(...batch);
38
+ cursor = nextCursor;
39
+ if (nfts.length >= total || !cursor)
40
+ break;
41
+ } while (nfts.length < maxNftSampleSize);
42
+ return nfts.map((nft) => {
43
+ return { ...nft, schema: NftSchema };
44
+ });
45
+ };
46
+ //# sourceMappingURL=getNftCollectionNfts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNftCollectionNfts.js","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAA2B,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAE3F,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAA;AAO/E,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK;AACvC;;GAEG;AACH,eAAuB;AACvB;;GAEG;AACH,OAAe;AACf,MAAM;AACN,mDAAmD;AACnD,MAAM;AACN,iDAAiD;AACjD;;GAEG;AACH,UAAkB;AAClB;;;;GAIG;AACH,gBAAgB,GAAG,GAAG,EACK,EAAE;IAC7B,IAAI,6BAA6B,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,EAAE;QACzE,MAAM,IAAI,KAAK,CAAC,uDAAuD,eAAe,EAAE,CAAC,CAAA;KAC1F;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAA;IAC7I,MAAM,IAAI,GAAc,EAAE,CAAA;IAC1B,IAAI,MAAM,GAAuB,SAAS,CAAA;IAC1C,GAAG;QACD,MAAM,IAAI,GAA2B,EAAE,eAAe,EAAE,MAAM,EAAE,CAAA;QAChE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAA;QAChG,MAAM,KAAK,GAAc,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QACjF,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;QACnB,MAAM,GAAG,UAAU,CAAA;QACnB,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,CAAC,MAAM;YAAE,MAAK;KAC3C,QAAQ,IAAI,CAAC,MAAM,GAAG,gBAAgB,EAAC;IACxC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,OAAO,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IACtC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { Auth, SDK } from '@infura/sdk';
2
+ import { nonEvaluableContractAddresses } from './nonEvaluableContractAddresses';
3
+ export const getNftCollectionTotalNfts = async (
4
+ /**
5
+ * The address of the NFT contract to search for
6
+ */
7
+ contractAddress,
8
+ /**
9
+ * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on
10
+ */
11
+ chainId,
12
+ // /**
13
+ // * The ethers provider to use to search for NFTs
14
+ // */
15
+ // provider: ExternalProvider | JsonRpcFetchFunc,
16
+ /**
17
+ * The private key of the wallet to use to search for NFTs
18
+ */
19
+ privateKey) => {
20
+ if (nonEvaluableContractAddresses.includes(contractAddress.toUpperCase())) {
21
+ throw new Error(`Unable to evaluate collection with contractAddress: ${contractAddress}`);
22
+ }
23
+ const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
24
+ const opts = { contractAddress };
25
+ const { total } = await sdk.api.getNFTsForCollection(opts);
26
+ return total;
27
+ };
28
+ //# sourceMappingURL=getNftCollectionTotalNfts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNftCollectionTotalNfts.js","sourceRoot":"","sources":["../../../src/lib/getNftCollectionTotalNfts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEvC,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAA;AAO/E,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK;AAC5C;;GAEG;AACH,eAAuB;AACvB;;GAEG;AACH,OAAe;AACf,MAAM;AACN,mDAAmD;AACnD,MAAM;AACN,iDAAiD;AACjD;;GAEG;AACH,UAAkB,EACD,EAAE;IACnB,IAAI,6BAA6B,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,EAAE;QACzE,MAAM,IAAI,KAAK,CAAC,uDAAuD,eAAe,EAAE,CAAC,CAAA;KAC1F;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAA;IAC7I,MAAM,IAAI,GAA2B,EAAE,eAAe,EAAE,CAAA;IACxD,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC1D,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
@@ -1,2 +1,5 @@
1
+ export * from './collectionMetrics';
1
2
  export * from './getNftCollectionInfo';
3
+ export * from './getNftCollectionNfts';
4
+ export * from './getNftCollectionTotalNfts';
2
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * These contracts are not evaluable for some
3
+ * reason (too large, nonsensical, etc.)
4
+ */
5
+ export const nonEvaluableContractAddresses = [
6
+ // ENS
7
+ '0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72',
8
+ ].map((address) => address.toUpperCase());
9
+ //# sourceMappingURL=nonEvaluableContractAddresses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonEvaluableContractAddresses.js","sourceRoot":"","sources":["../../../src/lib/nonEvaluableContractAddresses.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,MAAM;IACN,4CAA4C;CAC7C,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,0BAA0B,EAE3B,MAAM,mDAAmD,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAIrE,MAAM,MAAM,gCAAgC,GAAG,aAAa,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC,CAAA;AAEzG,qBAAa,0BAA0B,CACrC,OAAO,SAAS,gCAAgC,GAAG,gCAAgC,CACnF,SAAQ,eAAe,CAAC,OAAO,CAAC;IAChC,OAAgB,aAAa,uDAAqC;cAEzC,cAAc,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAalF"}
1
+ {"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../src/Witness.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,0BAA0B,EAE3B,MAAM,mDAAmD,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAIrE,MAAM,MAAM,gCAAgC,GAAG,aAAa,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC,CAAA;AAWzG,qBAAa,0BAA0B,CACrC,OAAO,SAAS,gCAAgC,GAAG,gCAAgC,CACnF,SAAQ,eAAe,CAAC,OAAO,CAAC;IAChC,OAAgB,aAAa,uDAAqC;cAEzC,cAAc,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CA0BlF"}
@@ -0,0 +1,13 @@
1
+ import { NftInfo } from '@xyo-network/crypto-nft-payload-plugin';
2
+ import { Distribution } from './lib';
3
+ export interface NftCollectionMetrics {
4
+ distribution: {
5
+ metadata: {
6
+ attributes: Distribution<{
7
+ [key: string]: string | number;
8
+ }>;
9
+ };
10
+ };
11
+ }
12
+ export declare const getNftCollectionMetrics: (nfts: NftInfo[]) => NftCollectionMetrics;
13
+ //# 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,OAAO,EAAuB,MAAM,wCAAwC,CAAA;AAErF,OAAO,EAAsC,YAAY,EAAE,MAAM,OAAO,CAAA;AAExE,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE;QACZ,QAAQ,EAAE;YACR,UAAU,EAAE,YAAY,CAAC;gBACvB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;aAC/B,CAAC,CAAA;SACH,CAAA;KACF,CAAA;CACF;AAED,eAAO,MAAM,uBAAuB,SAAU,OAAO,EAAE,KAAG,oBAczD,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './getNftCollectionMetrics';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/collectionMetrics/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Distribution } from './distribution';
2
+ export declare const calculateAllPropertiesDistribution: <T>(array: T[]) => Distribution<T>;
3
+ //# sourceMappingURL=calculateAllPropertiesDistribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculateAllPropertiesDistribution.d.ts","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/calculateAllPropertiesDistribution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,eAAO,MAAM,kCAAkC,oCAsB9C,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Distribution } from './distribution';
2
+ export declare const calculatePropertyDistribution: <T>(array: T[], property: keyof T) => Distribution<T>;
3
+ //# sourceMappingURL=calculatePropertyDistribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculatePropertyDistribution.d.ts","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/calculatePropertyDistribution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,eAAO,MAAM,6BAA6B,uDAgBzC,CAAA"}
@@ -0,0 +1,6 @@
1
+ export type Distribution<T> = {
2
+ [K in keyof T]?: {
3
+ [value: string]: number;
4
+ };
5
+ };
6
+ //# sourceMappingURL=distribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution.d.ts","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/distribution.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;KAC3B,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE;CAC7C,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './calculateAllPropertiesDistribution';
2
+ export * from './distribution';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/collectionMetrics/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA;AACpD,cAAc,gBAAgB,CAAA"}
@@ -1,8 +1,3 @@
1
- import { NftCollectionInfoPayload } from '@xyo-network/crypto-nft-collection-payload-plugin';
2
- /**
3
- * These contracts are not evaluable for some
4
- * reason (too large, nonsensical, etc.)
5
- */
6
- export declare const nonEvaluableContractAddresses: string[];
7
- export declare const getNftCollectionInfo: (contractAddress: string, chainId: number, privateKey: string, maxNftCount?: number) => Promise<NftCollectionInfoPayload>;
1
+ import { NftCollectionInfo } from '@xyo-network/crypto-nft-collection-payload-plugin';
2
+ export declare const getNftCollectionInfo: (contractAddress: string, chainId: number, privateKey: string) => Promise<Omit<NftCollectionInfo, 'total'>>;
8
3
  //# sourceMappingURL=getNftCollectionInfo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getNftCollectionInfo.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionInfo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAuB,MAAM,mDAAmD,CAAA;AAEjH;;;GAGG;AACH,eAAO,MAAM,6BAA6B,UAGD,CAAA;AAOzC,eAAO,MAAM,oBAAoB,oBAId,MAAM,WAId,MAAM,cAQH,MAAM,2BAMjB,QAAQ,wBAAwB,CAuBlC,CAAA"}
1
+ {"version":3,"file":"getNftCollectionInfo.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionInfo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAA;AASrF,eAAO,MAAM,oBAAoB,oBAId,MAAM,WAId,MAAM,cAQH,MAAM,KACjB,QAAQ,KAAK,iBAAiB,EAAE,OAAO,CAAC,CAQ1C,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { NftInfoPayload } from '@xyo-network/crypto-nft-payload-plugin';
2
+ export declare const getNftCollectionNfts: (contractAddress: string, chainId: number, privateKey: string, maxNftSampleSize?: number) => Promise<NftInfoPayload[]>;
3
+ //# sourceMappingURL=getNftCollectionNfts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNftCollectionNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionNfts.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,cAAc,EAAa,MAAM,wCAAwC,CAAA;AAS3F,eAAO,MAAM,oBAAoB,oBAId,MAAM,WAId,MAAM,cAQH,MAAM,gCAOjB,QAAQ,cAAc,EAAE,CAkB1B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const getNftCollectionTotalNfts: (contractAddress: string, chainId: number, privateKey: string) => Promise<number>;
2
+ //# sourceMappingURL=getNftCollectionTotalNfts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNftCollectionTotalNfts.d.ts","sourceRoot":"","sources":["../../../src/lib/getNftCollectionTotalNfts.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,yBAAyB,oBAInB,MAAM,WAId,MAAM,cAQH,MAAM,KACjB,QAAQ,MAAM,CAQhB,CAAA"}
@@ -1,2 +1,5 @@
1
+ export * from './collectionMetrics';
1
2
  export * from './getNftCollectionInfo';
3
+ export * from './getNftCollectionNfts';
4
+ export * from './getNftCollectionTotalNfts';
2
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * These contracts are not evaluable for some
3
+ * reason (too large, nonsensical, etc.)
4
+ */
5
+ export declare const nonEvaluableContractAddresses: string[];
6
+ //# sourceMappingURL=nonEvaluableContractAddresses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonEvaluableContractAddresses.d.ts","sourceRoot":"","sources":["../../../src/lib/nonEvaluableContractAddresses.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,6BAA6B,UAGD,CAAA"}
package/package.json CHANGED
@@ -12,12 +12,13 @@
12
12
  "dependencies": {
13
13
  "@infura/sdk": "^2.4.3",
14
14
  "@xylabs/assert": "^2.9.3",
15
- "@xyo-network/crypto-nft-collection-payload-plugin": "~2.70.5",
16
- "@xyo-network/crypto-nft-payload-plugin": "~2.70.5",
17
- "@xyo-network/module": "~2.70.5",
18
- "@xyo-network/payload-model": "~2.70.5",
19
- "@xyo-network/payloadset-plugin": "~2.70.5",
20
- "@xyo-network/witness": "~2.70.5"
15
+ "@xyo-network/core": "~2.70.6",
16
+ "@xyo-network/crypto-nft-collection-payload-plugin": "~2.70.6",
17
+ "@xyo-network/crypto-nft-payload-plugin": "~2.70.6",
18
+ "@xyo-network/module": "~2.70.6",
19
+ "@xyo-network/payload-model": "~2.70.6",
20
+ "@xyo-network/payloadset-plugin": "~2.70.6",
21
+ "@xyo-network/witness": "~2.70.6"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@xylabs/jest-helpers": "^2.9.3",
@@ -60,5 +61,5 @@
60
61
  },
61
62
  "sideEffects": false,
62
63
  "types": "dist/types/index.d.ts",
63
- "version": "2.70.5"
64
+ "version": "2.70.6"
64
65
  }
package/src/Witness.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { assertEx } from '@xylabs/assert'
2
+ import { PayloadHasher } from '@xyo-network/core'
2
3
  import {
3
4
  isNftCollectionWitnessQueryPayload,
5
+ NftCollectionInfoPayload,
6
+ NftCollectionSchema,
4
7
  NftCollectionWitnessConfig,
5
8
  NftCollectionWitnessConfigSchema,
6
9
  } from '@xyo-network/crypto-nft-collection-payload-plugin'
@@ -8,10 +11,19 @@ import { AnyConfigSchema } from '@xyo-network/module'
8
11
  import { Payload } from '@xyo-network/payload-model'
9
12
  import { AbstractWitness, WitnessParams } from '@xyo-network/witness'
10
13
 
11
- import { getNftCollectionInfo } from './lib'
14
+ import { getNftCollectionInfo, getNftCollectionMetrics, getNftCollectionNfts, getNftCollectionTotalNfts } from './lib'
12
15
 
13
16
  export type CryptoNftCollectionWitnessParams = WitnessParams<AnyConfigSchema<NftCollectionWitnessConfig>>
14
17
 
18
+ const defaultMaxNftSampleSize = 100
19
+
20
+ /**
21
+ * A "no operation" Promise to be used
22
+ * when no action is desired but a Promise
23
+ * is required to be returned
24
+ */
25
+ const NoOp = Promise.resolve()
26
+
15
27
  export class CryptoNftCollectionWitness<
16
28
  TParams extends CryptoNftCollectionWitnessParams = CryptoNftCollectionWitnessParams,
17
29
  > extends AbstractWitness<TParams> {
@@ -21,11 +33,24 @@ export class CryptoNftCollectionWitness<
21
33
  await this.started('throw')
22
34
  const queries = payloads?.filter(isNftCollectionWitnessQueryPayload) ?? []
23
35
  const observations = await Promise.all(
24
- queries.map(async (query) => {
36
+ queries.map<Promise<NftCollectionInfoPayload>>(async (query) => {
25
37
  const address = assertEx(query?.address || this.config.address, 'params.address is required')
26
38
  const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')
27
- const observation = await getNftCollectionInfo(address, chainId, this.account.private.hex)
28
- return observation
39
+ const maxNftSampleSize = query?.maxNftSampleSize || defaultMaxNftSampleSize
40
+ const [info, total, nfts, archivist] = await Promise.all([
41
+ getNftCollectionInfo(address, chainId, this.account.private.hex),
42
+ getNftCollectionTotalNfts(address, chainId, this.account.private.hex),
43
+ getNftCollectionNfts(address, chainId, this.account.private.hex, maxNftSampleSize),
44
+ this.writeArchivist(),
45
+ ])
46
+ const distribution = getNftCollectionMetrics(nfts)
47
+ const [sources] = await Promise.all([
48
+ // Hash all the payloads
49
+ Promise.all(nfts.map((nft) => PayloadHasher.hashAsync(nft))),
50
+ // Insert them into the archivist if we have one
51
+ archivist ? archivist.insert(nfts) : NoOp,
52
+ ])
53
+ return { ...info, ...distribution, schema: NftCollectionSchema, sources, total }
29
54
  }),
30
55
  )
31
56
  return observations.flat()
@@ -0,0 +1,29 @@
1
+ import { NftInfo, OpenSeaNftAttribute } from '@xyo-network/crypto-nft-payload-plugin'
2
+
3
+ import { calculateAllPropertiesDistribution, Distribution } from './lib'
4
+
5
+ export interface NftCollectionMetrics {
6
+ distribution: {
7
+ metadata: {
8
+ attributes: Distribution<{
9
+ [key: string]: string | number
10
+ }>
11
+ }
12
+ }
13
+ }
14
+
15
+ export const getNftCollectionMetrics = (nfts: NftInfo[]): NftCollectionMetrics => {
16
+ const attributes = nfts
17
+ .map((nft) => nft.metadata?.attributes as OpenSeaNftAttribute[])
18
+ .map((attributes) => {
19
+ return Object.fromEntries(attributes.map((attribute) => [attribute.trait_type, attribute.value]))
20
+ })
21
+ const distribution = calculateAllPropertiesDistribution(attributes)
22
+ return {
23
+ distribution: {
24
+ metadata: {
25
+ attributes: distribution,
26
+ },
27
+ },
28
+ }
29
+ }
@@ -0,0 +1 @@
1
+ export * from './getNftCollectionMetrics'
@@ -0,0 +1,25 @@
1
+ import { Distribution } from './distribution'
2
+
3
+ export const calculateAllPropertiesDistribution = <T>(array: T[]): Distribution<T> => {
4
+ const distribution: Distribution<T> = {}
5
+
6
+ array.forEach((item) => {
7
+ for (const property in item) {
8
+ if (Object.prototype.hasOwnProperty.call(item, property)) {
9
+ const value = item[property as keyof T]
10
+ if (value !== undefined && value !== null) {
11
+ const valueString = value.toString()
12
+ if (!distribution[property]) {
13
+ distribution[property] = { [valueString]: 1 }
14
+ } else if (!distribution[property]![valueString]) {
15
+ ;(distribution[property] as Record<string, number>)[valueString] = 1
16
+ } else {
17
+ ;(distribution[property] as Record<string, number>)[valueString] += 1
18
+ }
19
+ }
20
+ }
21
+ }
22
+ })
23
+
24
+ return distribution
25
+ }