@xyo-network/crypto-nft-witness-wallet-plugin 2.78.0 → 2.78.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 (55) hide show
  1. package/dist/browser/index.cjs +174 -35
  2. package/dist/browser/index.cjs.map +1 -1
  3. package/dist/browser/index.js +173 -34
  4. package/dist/browser/index.js.map +1 -1
  5. package/dist/browser/lib/getNftCollectionMetadata.d.cts +6 -0
  6. package/dist/browser/lib/getNftCollectionMetadata.d.cts.map +1 -0
  7. package/dist/browser/lib/getNftCollectionMetadata.d.mts +6 -0
  8. package/dist/browser/lib/getNftCollectionMetadata.d.mts.map +1 -0
  9. package/dist/browser/lib/getNftCollectionMetadata.d.ts +6 -0
  10. package/dist/browser/lib/getNftCollectionMetadata.d.ts.map +1 -0
  11. package/dist/browser/lib/getNftMetadata.d.cts +11 -0
  12. package/dist/browser/lib/getNftMetadata.d.cts.map +1 -0
  13. package/dist/browser/lib/getNftMetadata.d.mts +11 -0
  14. package/dist/browser/lib/getNftMetadata.d.mts.map +1 -0
  15. package/dist/browser/lib/getNftMetadata.d.ts +11 -0
  16. package/dist/browser/lib/getNftMetadata.d.ts.map +1 -0
  17. package/dist/browser/lib/getNftsOwnedByAddress.d.cts.map +1 -1
  18. package/dist/browser/lib/getNftsOwnedByAddress.d.mts.map +1 -1
  19. package/dist/browser/lib/getNftsOwnedByAddress.d.ts.map +1 -1
  20. package/dist/browser/lib/getProvider.d.cts +3 -0
  21. package/dist/browser/lib/getProvider.d.cts.map +1 -0
  22. package/dist/browser/lib/getProvider.d.mts +3 -0
  23. package/dist/browser/lib/getProvider.d.mts.map +1 -0
  24. package/dist/browser/lib/getProvider.d.ts +3 -0
  25. package/dist/browser/lib/getProvider.d.ts.map +1 -0
  26. package/dist/node/index.js +174 -36
  27. package/dist/node/index.js.map +1 -1
  28. package/dist/node/index.mjs +173 -35
  29. package/dist/node/index.mjs.map +1 -1
  30. package/dist/node/lib/getNftCollectionMetadata.d.cts +6 -0
  31. package/dist/node/lib/getNftCollectionMetadata.d.cts.map +1 -0
  32. package/dist/node/lib/getNftCollectionMetadata.d.mts +6 -0
  33. package/dist/node/lib/getNftCollectionMetadata.d.mts.map +1 -0
  34. package/dist/node/lib/getNftCollectionMetadata.d.ts +6 -0
  35. package/dist/node/lib/getNftCollectionMetadata.d.ts.map +1 -0
  36. package/dist/node/lib/getNftMetadata.d.cts +11 -0
  37. package/dist/node/lib/getNftMetadata.d.cts.map +1 -0
  38. package/dist/node/lib/getNftMetadata.d.mts +11 -0
  39. package/dist/node/lib/getNftMetadata.d.mts.map +1 -0
  40. package/dist/node/lib/getNftMetadata.d.ts +11 -0
  41. package/dist/node/lib/getNftMetadata.d.ts.map +1 -0
  42. package/dist/node/lib/getNftsOwnedByAddress.d.cts.map +1 -1
  43. package/dist/node/lib/getNftsOwnedByAddress.d.mts.map +1 -1
  44. package/dist/node/lib/getNftsOwnedByAddress.d.ts.map +1 -1
  45. package/dist/node/lib/getProvider.d.cts +3 -0
  46. package/dist/node/lib/getProvider.d.cts.map +1 -0
  47. package/dist/node/lib/getProvider.d.mts +3 -0
  48. package/dist/node/lib/getProvider.d.mts.map +1 -0
  49. package/dist/node/lib/getProvider.d.ts +3 -0
  50. package/dist/node/lib/getProvider.d.ts.map +1 -0
  51. package/package.json +10 -11
  52. package/src/lib/getNftCollectionMetadata.ts +60 -0
  53. package/src/lib/getNftMetadata.ts +79 -0
  54. package/src/lib/getNftsOwnedByAddress.ts +75 -39
  55. package/src/lib/getProvider.ts +17 -0
@@ -22,7 +22,7 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  CryptoWalletNftWitness: () => CryptoWalletNftWitness,
24
24
  CryptoWalletNftWitnessPlugin: () => CryptoWalletNftWitnessPlugin,
25
- checkIpfsUrl: () => checkIpfsUrl,
25
+ checkIpfsUrl: () => checkIpfsUrl2,
26
26
  default: () => src_default,
27
27
  getErc1155MetadataUri: () => getErc1155MetadataUri,
28
28
  getErc721MetadataUri: () => getErc721MetadataUri,
@@ -43,10 +43,9 @@ var import_abstract_witness = require("@xyo-network/abstract-witness");
43
43
  var import_crypto_nft_payload_plugin2 = require("@xyo-network/crypto-nft-payload-plugin");
44
44
 
45
45
  // src/lib/getNftsOwnedByAddress.ts
46
- var import_sdk = require("@infura/sdk");
47
- var import_axios = require("@xyo-network/axios");
46
+ var import_axios2 = require("@xyo-network/axios");
48
47
  var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
49
- var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
48
+ var import_open_zeppelin_typechain3 = require("@xyo-network/open-zeppelin-typechain");
50
49
 
51
50
  // src/lib/getInfuraProvider.ts
52
51
  var import_providers = require("@ethersproject/providers");
@@ -65,7 +64,54 @@ var getInfuraProviderConfig = () => {
65
64
  return { projectId, projectSecret };
66
65
  };
67
66
 
68
- // src/lib/getNftsOwnedByAddress.ts
67
+ // src/lib/getNftCollectionMetadata.ts
68
+ var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
69
+ var import_ethers = require("ethers");
70
+ function getInterfaceID(contractInterface) {
71
+ let interfaceID = import_ethers.constants.Zero;
72
+ const functions = Object.keys(contractInterface.functions);
73
+ for (let i = 0; i < functions.length; i++) {
74
+ interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
75
+ }
76
+ return interfaceID.toHexString();
77
+ }
78
+ var getNftCollectionMetadata = async (contractAddress, provider) => {
79
+ try {
80
+ const contract721 = import_open_zeppelin_typechain.ERC721Enumerable__factory.connect(contractAddress, provider);
81
+ const contract1155 = import_open_zeppelin_typechain.ERC1155__factory.connect(contractAddress, provider);
82
+ let name = "";
83
+ try {
84
+ name = await contract721.name();
85
+ } catch (ex) {
86
+ const error = ex;
87
+ console.log(`name: ${error.message}`);
88
+ }
89
+ let symbol = "";
90
+ try {
91
+ symbol = await contract721.symbol();
92
+ } catch (ex) {
93
+ const error = ex;
94
+ console.log(`symbol: ${error.message}`);
95
+ }
96
+ let is1155 = false;
97
+ try {
98
+ is1155 = await contract1155.supportsInterface(getInterfaceID(import_open_zeppelin_typechain.ERC1155__factory.getInterface(import_open_zeppelin_typechain.ERC1155__factory.abi)));
99
+ } catch (ex) {
100
+ const error = ex;
101
+ console.log(`is1155: ${error.message}`);
102
+ is1155 = false;
103
+ }
104
+ return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
105
+ } catch (ex) {
106
+ const error = ex;
107
+ console.error(`getNftCollectionMetadata: ${error.message}`);
108
+ throw ex;
109
+ }
110
+ };
111
+
112
+ // src/lib/getNftMetadata.ts
113
+ var import_axios = require("@xyo-network/axios");
114
+ var import_open_zeppelin_typechain2 = require("@xyo-network/open-zeppelin-typechain");
69
115
  var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
70
116
  var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
71
117
  const url = new URL(urlToCheck);
@@ -83,9 +129,71 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
83
129
  return urlToCheck;
84
130
  }
85
131
  };
132
+ var getNftMetadata = async (contractAddress, provider, tokenId) => {
133
+ const axios = new import_axios.AxiosJson({ timeout: 2e3 });
134
+ const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(contractAddress, provider);
135
+ const storage1155 = import_open_zeppelin_typechain2.ERC1155URIStorage__factory.connect(contractAddress, provider);
136
+ let uri1155;
137
+ try {
138
+ uri1155 = await storage1155.uri(tokenId);
139
+ } catch (ex) {
140
+ const error = ex;
141
+ console.error(`metaDataUri: ${error.message}`);
142
+ }
143
+ let metadataUri;
144
+ try {
145
+ metadataUri = await storage.tokenURI(tokenId);
146
+ } catch (ex) {
147
+ const error = ex;
148
+ console.error(`metadataUri: ${error.message}`);
149
+ }
150
+ const tokenMetadataUri = metadataUri ?? uri1155;
151
+ const checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri;
152
+ let metadata = void 0;
153
+ try {
154
+ metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : void 0;
155
+ } catch (ex) {
156
+ const error = ex;
157
+ console.error(`metadata: ${error.message}`);
158
+ }
159
+ return [tokenMetadataUri, metadata];
160
+ };
161
+
162
+ // src/lib/getProvider.ts
163
+ var import_providers2 = require("@ethersproject/providers");
164
+ var getProviderFromEnv = (chainId = "homestead") => {
165
+ const infuraWssUri = process.env.INFURA_WSS_URI;
166
+ const infuraProvider = new import_providers2.InfuraProvider("homestead", {
167
+ projectId: process.env.INFURA_PROJECT_ID,
168
+ projectSecret: process.env.INFURA_PROJECT_SECRET
169
+ });
170
+ const infuraWebsocketProvider = infuraWssUri ? new import_providers2.WebSocketProvider(infuraWssUri, chainId) : void 0;
171
+ const quickNodeUri = process.env.QUICKNODE_WSS_URI;
172
+ const quickNodeProvider = quickNodeUri ? new import_providers2.WebSocketProvider(quickNodeUri, chainId) : void 0;
173
+ const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
174
+ return provider;
175
+ };
176
+
177
+ // src/lib/getNftsOwnedByAddress.ts
178
+ var checkIpfsUrl2 = (urlToCheck, ipfsGateway2) => {
179
+ const url = new URL(urlToCheck);
180
+ let protocol = url.protocol;
181
+ let host = url.host;
182
+ let path = url.pathname;
183
+ const query = url.search;
184
+ if (protocol === "ipfs:") {
185
+ protocol = "https:";
186
+ host = ipfsGateway2;
187
+ path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
188
+ const root = `${protocol}//${host}/${path}`;
189
+ return query?.length > 0 ? `${root}?${query}` : root;
190
+ } else {
191
+ return urlToCheck;
192
+ }
193
+ };
86
194
  var getErc721MetadataUri = async (address, tokenId) => {
87
195
  try {
88
- const contract = import_open_zeppelin_typechain.ERC721__factory.connect(address, getInfuraProvider());
196
+ const contract = import_open_zeppelin_typechain3.ERC721__factory.connect(address, getInfuraProvider());
89
197
  return [await contract.tokenURI(tokenId), void 0];
90
198
  } catch (ex) {
91
199
  return [void 0, ex];
@@ -93,7 +201,7 @@ var getErc721MetadataUri = async (address, tokenId) => {
93
201
  };
94
202
  var getErc1155MetadataUri = async (address, tokenId) => {
95
203
  try {
96
- const contract = import_open_zeppelin_typechain.ERC1155__factory.connect(address, getInfuraProvider());
204
+ const contract = import_open_zeppelin_typechain3.ERC1155__factory.connect(address, getInfuraProvider());
97
205
  return [await contract.uri(tokenId), void 0];
98
206
  } catch (ex) {
99
207
  return [void 0, ex];
@@ -104,40 +212,71 @@ var getNftMetadataUri = async (address, tokenId) => {
104
212
  return results[0][0] ?? results[1][0];
105
213
  };
106
214
  var getNftsOwnedByAddress = async (publicAddress, chainId, privateKey, maxNfts = 1e3, timeout = 2e3) => {
107
- const sdk = new import_sdk.SDK(new import_sdk.Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
108
- const nfts = [];
109
- const axios = new import_axios.AxiosJson();
110
- let cursor = void 0;
111
- do {
112
- const opts = { cursor, includeMetadata: true, publicAddress };
113
- const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTs(opts);
114
- const batch = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {
115
- const { contract: address, type: tokenType, ...rest } = asset;
116
- const type = (0, import_crypto_nft_payload_plugin.toTokenType)(tokenType);
117
- return { address, chainId, type, ...rest };
118
- });
119
- nfts.push(...batch);
120
- cursor = nextCursor;
121
- if (nfts.length >= total || !cursor)
122
- break;
123
- } while (nfts.length < maxNfts);
124
- return await Promise.all(
125
- nfts.map(async (nft) => {
126
- const metaDataUri = await getNftMetadataUri(nft.address, nft.tokenId);
127
- if (metaDataUri) {
128
- nft.metaDataUri = metaDataUri;
129
- const cookedUri = checkIpfsUrl(metaDataUri, ipfsGateway);
215
+ const axios = new import_axios2.AxiosJson({ timeout });
216
+ const provider = getProviderFromEnv();
217
+ const qnUri = "https://api.quicknode.com/graphql";
218
+ const result = await axios.post(qnUri, {
219
+ query: `query Query {
220
+ ethereum {
221
+ walletByAddress(address: "${publicAddress}") {
222
+ walletNFTs (first: ${maxNfts}) {
223
+ edges {
224
+ node {
225
+ nft {
226
+ contractAddress
227
+ metadata
228
+ tokenId
229
+ externalUrl
230
+ name
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+ }`,
238
+ variables: {}
239
+ });
240
+ const nftResult = await Promise.all(
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
242
+ Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft) => {
243
+ try {
244
+ const { contractAddress, tokenId, metadata, externalUrl } = nft.node.nft;
245
+ let supply = "0x01";
246
+ let type = (0, import_crypto_nft_payload_plugin.toTokenType)("ERC721");
130
247
  try {
131
- nft.metadata = (await axios.get(cookedUri, { timeout }))?.data;
248
+ const supply1155 = import_open_zeppelin_typechain3.ERC1155Supply__factory.connect(contractAddress, provider);
249
+ const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider);
250
+ type = nftType;
251
+ supply = nftType === (0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
132
252
  } catch (ex) {
133
- console.log(`failed to get NTF metadata [${cookedUri}] [${ex}]`);
253
+ const error = ex;
254
+ console.error(`supply: ${error.message}`);
255
+ }
256
+ const fields = {
257
+ address: contractAddress,
258
+ chainId,
259
+ metadata,
260
+ metadataUri: externalUrl,
261
+ supply,
262
+ tokenId,
263
+ type
264
+ };
265
+ if (!fields.metadataUri || !fields.metadata) {
266
+ const [metadataUri, metadata2] = await getNftMetadata(contractAddress, provider, fields.tokenId);
267
+ fields.metadata = metadata2;
268
+ fields.metadataUri = metadataUri;
134
269
  }
135
- } else {
136
- console.log("failed to get NTF metadata URI");
270
+ return fields;
271
+ } catch (ex) {
272
+ const error = ex;
273
+ console.error(`Error: ${error.message}`);
274
+ console.error(`${error.stack}`);
275
+ throw ex;
137
276
  }
138
- return nft;
139
277
  })
140
278
  );
279
+ return nftResult;
141
280
  };
142
281
 
143
282
  // src/Witness.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/getNftsOwnedByAddress.ts","../../src/lib/getInfuraProvider.ts"],"sourcesContent":["import { CryptoWalletNftWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoWalletNftWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoWalletNftWitnessPlugin\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 { CryptoWalletNftWitness } from './Witness'\n\nexport const CryptoWalletNftWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoWalletNftWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoWalletNftWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport {\n CryptoWalletNftWitnessConfig,\n isNftWitnessQuery,\n NftInfo,\n NftSchema,\n NftWitnessConfigSchema,\n NftWitnessQuery,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftsOwnedByAddress } from './lib'\n\nexport type CryptoWalletNftWitnessParams = WitnessParams<AnyConfigSchema<CryptoWalletNftWitnessConfig>>\n\nconst schema = NftSchema\n\nconst defaultMaxNfts = 100\n\nexport class CryptoWalletNftWitness<TParams extends CryptoWalletNftWitnessParams = CryptoWalletNftWitnessParams> extends AbstractWitness<\n TParams,\n NftWitnessQuery,\n NftInfo\n> {\n static override configSchemas = [NftWitnessConfigSchema]\n\n get timeout() {\n return this.config.timeout ?? 2000\n }\n\n protected override async observeHandler(payloads?: NftWitnessQuery[]): Promise<NftInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map(async (query) => {\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n try {\n const nfts = await getNftsOwnedByAddress(address, chainId, this.account.private.hex, maxNfts, this.timeout)\n const observation = nfts.map<NftInfo>((nft) => {\n return { ...nft, schema }\n })\n return observation\n } catch (error) {\n throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}`)\n }\n }),\n )\n return observations.flat()\n }\n}\n","import { Auth, SDK } from '@infura/sdk'\nimport { AxiosJson } from '@xyo-network/axios'\nimport { NftInfoFields, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getInfuraProvider } from './getInfuraProvider'\n\ntype PublicAddressOptions = {\n cursor?: string\n includeMetadata?: boolean\n publicAddress: string\n tokenAddresses?: string[]\n}\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n}\n\nexport const getErc721MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC721__factory.connect(address, getInfuraProvider())\n return [await contract.tokenURI(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getErc1155MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC1155__factory.connect(address, getInfuraProvider())\n return [await contract.uri(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getNftMetadataUri = async (address: string, tokenId: string) => {\n const results = await Promise.all([getErc721MetadataUri(address, tokenId), getErc1155MetadataUri(address, tokenId)])\n return results[0][0] ?? results[1][0]\n}\n\nexport const getNftsOwnedByAddress = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param chainId The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on */\n chainId: number,\n /** @param privateKey The private key of the wallet to use to search for NFTs */\n privateKey: string,\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 1000,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 2000,\n): Promise<NftInfoFields[]> => {\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 const axios = new AxiosJson()\n let cursor: string | undefined = undefined\n do {\n const opts: PublicAddressOptions = { cursor, includeMetadata: true, publicAddress }\n const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTs(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\n return await Promise.all(\n nfts.map(async (nft) => {\n const metaDataUri = await getNftMetadataUri(nft.address, nft.tokenId)\n if (metaDataUri) {\n nft.metaDataUri = metaDataUri\n const cookedUri = checkIpfsUrl(metaDataUri, ipfsGateway)\n try {\n nft.metadata = (await axios.get(cookedUri, { timeout }))?.data\n } catch (ex) {\n console.log(`failed to get NTF metadata [${cookedUri}] [${ex}]`)\n }\n } else {\n console.log('failed to get NTF metadata URI')\n }\n return nft\n }),\n )\n}\n","import { InfuraProvider, Provider } from '@ethersproject/providers'\nimport { assertEx } from '@xylabs/assert'\n\nexport interface InfuraProviderConfig {\n projectId: string\n projectSecret: string\n}\n\nlet instance: InfuraProvider | undefined = undefined\n\nexport const getInfuraProvider = (): Provider => {\n if (instance) return instance\n const config = getInfuraProviderConfig()\n instance = new InfuraProvider('homestead', config)\n return instance\n}\n\nexport const canUseInfuraProvider = (): boolean => {\n return !!process.env.INFURA_PROJECT_ID && !!process.env.INFURA_PROJECT_SECRET ? true : false\n}\n\nexport const getInfuraProviderConfig = (): InfuraProviderConfig => {\n const projectId = assertEx(process.env.INFURA_PROJECT_ID, 'Missing INFURA_PROJECT_ID ENV VAR')\n const projectSecret = assertEx(process.env.INFURA_PROJECT_SECRET, 'Missing INFURA_PROJECT_SECRET ENV VAR')\n return { projectId, projectSecret }\n}\n"],"mappings":"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","names":["import_crypto_nft_payload_plugin","import_assert","import_crypto_nft_payload_plugin","ipfsGateway"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/getNftsOwnedByAddress.ts","../../src/lib/getInfuraProvider.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getNftMetadata.ts","../../src/lib/getProvider.ts"],"sourcesContent":["import { CryptoWalletNftWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoWalletNftWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoWalletNftWitnessPlugin\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 { CryptoWalletNftWitness } from './Witness'\n\nexport const CryptoWalletNftWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoWalletNftWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoWalletNftWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport {\n CryptoWalletNftWitnessConfig,\n isNftWitnessQuery,\n NftInfo,\n NftSchema,\n NftWitnessConfigSchema,\n NftWitnessQuery,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftsOwnedByAddress } from './lib'\n\nexport type CryptoWalletNftWitnessParams = WitnessParams<AnyConfigSchema<CryptoWalletNftWitnessConfig>>\n\nconst schema = NftSchema\n\nconst defaultMaxNfts = 100\n\nexport class CryptoWalletNftWitness<TParams extends CryptoWalletNftWitnessParams = CryptoWalletNftWitnessParams> extends AbstractWitness<\n TParams,\n NftWitnessQuery,\n NftInfo\n> {\n static override configSchemas = [NftWitnessConfigSchema]\n\n get timeout() {\n return this.config.timeout ?? 2000\n }\n\n protected override async observeHandler(payloads?: NftWitnessQuery[]): Promise<NftInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map(async (query) => {\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n try {\n const nfts = await getNftsOwnedByAddress(address, chainId, this.account.private.hex, maxNfts, this.timeout)\n const observation = nfts.map<NftInfo>((nft) => {\n return { ...nft, schema }\n })\n return observation\n } catch (error) {\n throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}`)\n }\n }),\n )\n return observations.flat()\n }\n}\n","import { AxiosJson } from '@xyo-network/axios'\nimport { NftInfoFields, NftMetadata, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getInfuraProvider } from './getInfuraProvider'\nimport { getNftCollectionMetadata } from './getNftCollectionMetadata'\nimport { getNftMetadata } from './getNftMetadata'\nimport { getProviderFromEnv } from './getProvider'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n}\n\nexport const getErc721MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC721__factory.connect(address, getInfuraProvider())\n return [await contract.tokenURI(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getErc1155MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC1155__factory.connect(address, getInfuraProvider())\n return [await contract.uri(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getNftMetadataUri = async (address: string, tokenId: string) => {\n const results = await Promise.all([getErc721MetadataUri(address, tokenId), getErc1155MetadataUri(address, tokenId)])\n return results[0][0] ?? results[1][0]\n}\n\ninterface QuickNodeNft {\n contractAddress: string\n externalUrl: string\n metadata: NftMetadata\n name: string\n tokenId: string\n}\n\nexport const getNftsOwnedByAddress = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param chainId The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on */\n chainId: number,\n /** @param privateKey The private key of the wallet to use to search for NFTs */\n privateKey: string,\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 1000,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 2000,\n): Promise<NftInfoFields[]> => {\n const axios = new AxiosJson({ timeout })\n const provider = getProviderFromEnv()\n\n const qnUri = 'https://api.quicknode.com/graphql'\n\n const result = await axios.post(qnUri, {\n query: `query Query {\n ethereum {\n walletByAddress(address: \"${publicAddress}\") {\n walletNFTs (first: ${maxNfts}) {\n edges {\n node {\n nft {\n contractAddress\n metadata\n tokenId\n externalUrl\n name\n }\n }\n }\n }\n }\n }\n }`,\n variables: {},\n })\n\n const nftResult = await Promise.all(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft: any) => {\n try {\n const { contractAddress, tokenId, metadata, externalUrl } = nft.node.nft as QuickNodeNft\n let supply = '0x01'\n let type = toTokenType('ERC721')\n try {\n const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider)\n const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider)\n type = nftType\n supply = nftType === toTokenType('ERC1155') ? (await supply1155.totalSupply(tokenId)).toHexString() : '0x01'\n } catch (ex) {\n const error = ex as Error\n console.error(`supply: ${error.message}`)\n }\n const fields: NftInfoFields = {\n address: contractAddress,\n chainId,\n metadata,\n metadataUri: externalUrl,\n supply,\n tokenId,\n type,\n }\n if (!fields.metadataUri || !fields.metadata) {\n const [metadataUri, metadata] = await getNftMetadata(contractAddress, provider, fields.tokenId)\n fields.metadata = metadata\n fields.metadataUri = metadataUri\n }\n return fields\n } catch (ex) {\n const error = ex as Error\n console.error(`Error: ${error.message}`)\n console.error(`${error.stack}`)\n throw ex\n }\n }),\n )\n\n return nftResult\n}\n","import { InfuraProvider, Provider } from '@ethersproject/providers'\nimport { assertEx } from '@xylabs/assert'\n\nexport interface InfuraProviderConfig {\n projectId: string\n projectSecret: string\n}\n\nlet instance: InfuraProvider | undefined = undefined\n\nexport const getInfuraProvider = (): Provider => {\n if (instance) return instance\n const config = getInfuraProviderConfig()\n instance = new InfuraProvider('homestead', config)\n return instance\n}\n\nexport const canUseInfuraProvider = (): boolean => {\n return !!process.env.INFURA_PROJECT_ID && !!process.env.INFURA_PROJECT_SECRET ? true : false\n}\n\nexport const getInfuraProviderConfig = (): InfuraProviderConfig => {\n const projectId = assertEx(process.env.INFURA_PROJECT_ID, 'Missing INFURA_PROJECT_ID ENV VAR')\n const projectSecret = assertEx(process.env.INFURA_PROJECT_SECRET, 'Missing INFURA_PROJECT_SECRET ENV VAR')\n return { projectId, projectSecret }\n}\n","import { Interface } from '@ethersproject/abi'\nimport { JsonRpcProvider } from '@ethersproject/providers'\nimport { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { ERC721Enumerable__factory, ERC1155__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { constants } from 'ethers'\n\nimport { getProviderFromEnv } from './getProvider'\n\nexport function getInterfaceID(contractInterface: Interface) {\n let interfaceID = constants.Zero\n const functions: string[] = Object.keys(contractInterface.functions)\n for (let i = 0; i < functions.length; i++) {\n interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]))\n }\n\n return interfaceID.toHexString()\n}\n\nexport const getNftCollectionMetadata = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: JsonRpcProvider,\n): Promise<Omit<NftCollectionMetadata, 'total'>> => {\n try {\n const contract721 = ERC721Enumerable__factory.connect(contractAddress, provider)\n const contract1155 = ERC1155__factory.connect(contractAddress, provider)\n let name: string = ''\n try {\n name = await contract721.name()\n } catch (ex) {\n const error = ex as Error\n console.log(`name: ${error.message}`)\n }\n let symbol: string = ''\n try {\n symbol = await contract721.symbol()\n } catch (ex) {\n const error = ex as Error\n console.log(`symbol: ${error.message}`)\n }\n let is1155: boolean = false\n try {\n is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)))\n } catch (ex) {\n const error = ex as Error\n console.log(`is1155: ${error.message}`)\n is1155 = false\n }\n return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? 'ERC1155' : 'ERC721' }\n } catch (ex) {\n const error = ex as Error\n console.error(`getNftCollectionMetadata: ${error.message}`)\n throw ex\n }\n}\n","import { JsonRpcProvider } from '@ethersproject/providers'\nimport { AxiosJson } from '@xyo-network/axios'\nimport { NftMetadata } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721URIStorage__factory, ERC1155URIStorage__factory } from '@xyo-network/open-zeppelin-typechain'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n}\n\nexport const getNftMetadata = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: JsonRpcProvider,\n /**\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 tokenId: string,\n): Promise<[string | undefined, NftMetadata | undefined]> => {\n const axios = new AxiosJson({ timeout: 2000 })\n const storage = ERC721URIStorage__factory.connect(contractAddress, provider)\n const storage1155 = ERC1155URIStorage__factory.connect(contractAddress, provider)\n\n let uri1155: string | undefined\n try {\n uri1155 = await storage1155.uri(tokenId)\n } catch (ex) {\n const error = ex as Error\n console.error(`metaDataUri: ${error.message}`)\n }\n\n let metadataUri: string | undefined\n try {\n metadataUri = await storage.tokenURI(tokenId)\n } catch (ex) {\n const error = ex as Error\n console.error(`metadataUri: ${error.message}`)\n }\n\n const tokenMetadataUri = metadataUri ?? uri1155\n\n const checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri\n let metadata: NftMetadata | undefined = undefined\n try {\n metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : undefined\n } catch (ex) {\n const error = ex as Error\n console.error(`metadata: ${error.message}`)\n }\n\n return [tokenMetadataUri, metadata]\n}\n","import { InfuraProvider, WebSocketProvider } from '@ethersproject/providers'\n\nexport const getProviderFromEnv = (chainId: string | number = 'homestead') => {\n const infuraWssUri = process.env.INFURA_WSS_URI\n const infuraProvider = new InfuraProvider('homestead', {\n projectId: process.env.INFURA_PROJECT_ID,\n projectSecret: process.env.INFURA_PROJECT_SECRET,\n })\n\n const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : undefined\n\n const quickNodeUri = process.env.QUICKNODE_WSS_URI\n const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : undefined\n\n const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider\n return provider\n}\n"],"mappings":"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","names":["checkIpfsUrl","import_crypto_nft_payload_plugin","import_assert","import_crypto_nft_payload_plugin","import_axios","import_open_zeppelin_typechain","import_open_zeppelin_typechain","ipfsGateway","import_providers","checkIpfsUrl","ipfsGateway","metadata"]}
@@ -14,10 +14,9 @@ import {
14
14
  } from "@xyo-network/crypto-nft-payload-plugin";
15
15
 
16
16
  // src/lib/getNftsOwnedByAddress.ts
17
- import { Auth, SDK } from "@infura/sdk";
18
- import { AxiosJson } from "@xyo-network/axios";
17
+ import { AxiosJson as AxiosJson2 } from "@xyo-network/axios";
19
18
  import { toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
20
- import { ERC721__factory, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
19
+ import { ERC721__factory, ERC1155__factory as ERC1155__factory2, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
21
20
 
22
21
  // src/lib/getInfuraProvider.ts
23
22
  import { InfuraProvider } from "@ethersproject/providers";
@@ -36,7 +35,54 @@ var getInfuraProviderConfig = () => {
36
35
  return { projectId, projectSecret };
37
36
  };
38
37
 
39
- // src/lib/getNftsOwnedByAddress.ts
38
+ // src/lib/getNftCollectionMetadata.ts
39
+ import { ERC721Enumerable__factory, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
40
+ import { constants } from "ethers";
41
+ function getInterfaceID(contractInterface) {
42
+ let interfaceID = constants.Zero;
43
+ const functions = Object.keys(contractInterface.functions);
44
+ for (let i = 0; i < functions.length; i++) {
45
+ interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
46
+ }
47
+ return interfaceID.toHexString();
48
+ }
49
+ var getNftCollectionMetadata = async (contractAddress, provider) => {
50
+ try {
51
+ const contract721 = ERC721Enumerable__factory.connect(contractAddress, provider);
52
+ const contract1155 = ERC1155__factory.connect(contractAddress, provider);
53
+ let name = "";
54
+ try {
55
+ name = await contract721.name();
56
+ } catch (ex) {
57
+ const error = ex;
58
+ console.log(`name: ${error.message}`);
59
+ }
60
+ let symbol = "";
61
+ try {
62
+ symbol = await contract721.symbol();
63
+ } catch (ex) {
64
+ const error = ex;
65
+ console.log(`symbol: ${error.message}`);
66
+ }
67
+ let is1155 = false;
68
+ try {
69
+ is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)));
70
+ } catch (ex) {
71
+ const error = ex;
72
+ console.log(`is1155: ${error.message}`);
73
+ is1155 = false;
74
+ }
75
+ return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
76
+ } catch (ex) {
77
+ const error = ex;
78
+ console.error(`getNftCollectionMetadata: ${error.message}`);
79
+ throw ex;
80
+ }
81
+ };
82
+
83
+ // src/lib/getNftMetadata.ts
84
+ import { AxiosJson } from "@xyo-network/axios";
85
+ import { ERC721URIStorage__factory, ERC1155URIStorage__factory } from "@xyo-network/open-zeppelin-typechain";
40
86
  var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
41
87
  var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
42
88
  const url = new URL(urlToCheck);
@@ -54,6 +100,68 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
54
100
  return urlToCheck;
55
101
  }
56
102
  };
103
+ var getNftMetadata = async (contractAddress, provider, tokenId) => {
104
+ const axios = new AxiosJson({ timeout: 2e3 });
105
+ const storage = ERC721URIStorage__factory.connect(contractAddress, provider);
106
+ const storage1155 = ERC1155URIStorage__factory.connect(contractAddress, provider);
107
+ let uri1155;
108
+ try {
109
+ uri1155 = await storage1155.uri(tokenId);
110
+ } catch (ex) {
111
+ const error = ex;
112
+ console.error(`metaDataUri: ${error.message}`);
113
+ }
114
+ let metadataUri;
115
+ try {
116
+ metadataUri = await storage.tokenURI(tokenId);
117
+ } catch (ex) {
118
+ const error = ex;
119
+ console.error(`metadataUri: ${error.message}`);
120
+ }
121
+ const tokenMetadataUri = metadataUri ?? uri1155;
122
+ const checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri;
123
+ let metadata = void 0;
124
+ try {
125
+ metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : void 0;
126
+ } catch (ex) {
127
+ const error = ex;
128
+ console.error(`metadata: ${error.message}`);
129
+ }
130
+ return [tokenMetadataUri, metadata];
131
+ };
132
+
133
+ // src/lib/getProvider.ts
134
+ import { InfuraProvider as InfuraProvider2, WebSocketProvider } from "@ethersproject/providers";
135
+ var getProviderFromEnv = (chainId = "homestead") => {
136
+ const infuraWssUri = process.env.INFURA_WSS_URI;
137
+ const infuraProvider = new InfuraProvider2("homestead", {
138
+ projectId: process.env.INFURA_PROJECT_ID,
139
+ projectSecret: process.env.INFURA_PROJECT_SECRET
140
+ });
141
+ const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : void 0;
142
+ const quickNodeUri = process.env.QUICKNODE_WSS_URI;
143
+ const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : void 0;
144
+ const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
145
+ return provider;
146
+ };
147
+
148
+ // src/lib/getNftsOwnedByAddress.ts
149
+ var checkIpfsUrl2 = (urlToCheck, ipfsGateway2) => {
150
+ const url = new URL(urlToCheck);
151
+ let protocol = url.protocol;
152
+ let host = url.host;
153
+ let path = url.pathname;
154
+ const query = url.search;
155
+ if (protocol === "ipfs:") {
156
+ protocol = "https:";
157
+ host = ipfsGateway2;
158
+ path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
159
+ const root = `${protocol}//${host}/${path}`;
160
+ return query?.length > 0 ? `${root}?${query}` : root;
161
+ } else {
162
+ return urlToCheck;
163
+ }
164
+ };
57
165
  var getErc721MetadataUri = async (address, tokenId) => {
58
166
  try {
59
167
  const contract = ERC721__factory.connect(address, getInfuraProvider());
@@ -64,7 +172,7 @@ var getErc721MetadataUri = async (address, tokenId) => {
64
172
  };
65
173
  var getErc1155MetadataUri = async (address, tokenId) => {
66
174
  try {
67
- const contract = ERC1155__factory.connect(address, getInfuraProvider());
175
+ const contract = ERC1155__factory2.connect(address, getInfuraProvider());
68
176
  return [await contract.uri(tokenId), void 0];
69
177
  } catch (ex) {
70
178
  return [void 0, ex];
@@ -75,40 +183,71 @@ var getNftMetadataUri = async (address, tokenId) => {
75
183
  return results[0][0] ?? results[1][0];
76
184
  };
77
185
  var getNftsOwnedByAddress = async (publicAddress, chainId, privateKey, maxNfts = 1e3, timeout = 2e3) => {
78
- const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }));
79
- const nfts = [];
80
- const axios = new AxiosJson();
81
- let cursor = void 0;
82
- do {
83
- const opts = { cursor, includeMetadata: true, publicAddress };
84
- const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTs(opts);
85
- const batch = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {
86
- const { contract: address, type: tokenType, ...rest } = asset;
87
- const type = toTokenType(tokenType);
88
- return { address, chainId, type, ...rest };
89
- });
90
- nfts.push(...batch);
91
- cursor = nextCursor;
92
- if (nfts.length >= total || !cursor)
93
- break;
94
- } while (nfts.length < maxNfts);
95
- return await Promise.all(
96
- nfts.map(async (nft) => {
97
- const metaDataUri = await getNftMetadataUri(nft.address, nft.tokenId);
98
- if (metaDataUri) {
99
- nft.metaDataUri = metaDataUri;
100
- const cookedUri = checkIpfsUrl(metaDataUri, ipfsGateway);
186
+ const axios = new AxiosJson2({ timeout });
187
+ const provider = getProviderFromEnv();
188
+ const qnUri = "https://api.quicknode.com/graphql";
189
+ const result = await axios.post(qnUri, {
190
+ query: `query Query {
191
+ ethereum {
192
+ walletByAddress(address: "${publicAddress}") {
193
+ walletNFTs (first: ${maxNfts}) {
194
+ edges {
195
+ node {
196
+ nft {
197
+ contractAddress
198
+ metadata
199
+ tokenId
200
+ externalUrl
201
+ name
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }`,
209
+ variables: {}
210
+ });
211
+ const nftResult = await Promise.all(
212
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
213
+ Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft) => {
214
+ try {
215
+ const { contractAddress, tokenId, metadata, externalUrl } = nft.node.nft;
216
+ let supply = "0x01";
217
+ let type = toTokenType("ERC721");
101
218
  try {
102
- nft.metadata = (await axios.get(cookedUri, { timeout }))?.data;
219
+ const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider);
220
+ const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider);
221
+ type = nftType;
222
+ supply = nftType === toTokenType("ERC1155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
103
223
  } catch (ex) {
104
- console.log(`failed to get NTF metadata [${cookedUri}] [${ex}]`);
224
+ const error = ex;
225
+ console.error(`supply: ${error.message}`);
226
+ }
227
+ const fields = {
228
+ address: contractAddress,
229
+ chainId,
230
+ metadata,
231
+ metadataUri: externalUrl,
232
+ supply,
233
+ tokenId,
234
+ type
235
+ };
236
+ if (!fields.metadataUri || !fields.metadata) {
237
+ const [metadataUri, metadata2] = await getNftMetadata(contractAddress, provider, fields.tokenId);
238
+ fields.metadata = metadata2;
239
+ fields.metadataUri = metadataUri;
105
240
  }
106
- } else {
107
- console.log("failed to get NTF metadata URI");
241
+ return fields;
242
+ } catch (ex) {
243
+ const error = ex;
244
+ console.error(`Error: ${error.message}`);
245
+ console.error(`${error.stack}`);
246
+ throw ex;
108
247
  }
109
- return nft;
110
248
  })
111
249
  );
250
+ return nftResult;
112
251
  };
113
252
 
114
253
  // src/Witness.ts
@@ -161,7 +300,7 @@ var src_default = CryptoWalletNftWitnessPlugin;
161
300
  export {
162
301
  CryptoWalletNftWitness,
163
302
  CryptoWalletNftWitnessPlugin,
164
- checkIpfsUrl,
303
+ checkIpfsUrl2 as checkIpfsUrl,
165
304
  src_default as default,
166
305
  getErc1155MetadataUri,
167
306
  getErc721MetadataUri,