@xyo-network/crypto-nft-witness-wallet-plugin 2.99.5 → 2.99.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.
@@ -5,7 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
8
  var __export = (target, all) => {
10
9
  for (var name in all)
11
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -49,7 +48,7 @@ module.exports = __toCommonJS(src_exports);
49
48
 
50
49
  // src/lib/contractHasFunctions.ts
51
50
  var import_assert = require("@xylabs/assert");
52
- var contractHasFunctions = /* @__PURE__ */ __name(async (provider, address, contractInterface, functionNames) => {
51
+ var contractHasFunctions = async (provider, address, contractInterface, functionNames) => {
53
52
  try {
54
53
  const bytecode = await provider.getCode(address, "latest");
55
54
  for (const functionName of functionNames) {
@@ -65,7 +64,7 @@ var contractHasFunctions = /* @__PURE__ */ __name(async (provider, address, cont
65
64
  console.log(error);
66
65
  return false;
67
66
  }
68
- }, "contractHasFunctions");
67
+ };
69
68
 
70
69
  // src/lib/getNftsOwnedByAddress.ts
71
70
  var import_hex = require("@xylabs/hex");
@@ -82,23 +81,14 @@ var import_parse_data_url = __toESM(require("parse-data-url"), 1);
82
81
 
83
82
  // src/lib/tokenTypes.ts
84
83
  var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
85
- var isErc1155 = /* @__PURE__ */ __name(async (provider, address) => {
86
- return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC1155URIStorage__factory.createInterface(), [
87
- "uri"
88
- ]);
89
- }, "isErc1155");
90
- var isErc721 = /* @__PURE__ */ __name(async (provider, address) => {
91
- return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.IERC721Metadata__factory.createInterface(), [
92
- "name",
93
- "symbol",
94
- "tokenURI"
95
- ]);
96
- }, "isErc721");
97
- var tokenTypes = /* @__PURE__ */ __name(async (provider, address) => {
98
- const [erc721, erc1155] = await Promise.all([
99
- isErc721(provider, address),
100
- isErc1155(provider, address)
101
- ]);
84
+ var isErc1155 = async (provider, address) => {
85
+ return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.ERC1155URIStorage__factory.createInterface(), ["uri"]);
86
+ };
87
+ var isErc721 = async (provider, address) => {
88
+ return await contractHasFunctions(provider, address, import_open_zeppelin_typechain.IERC721Metadata__factory.createInterface(), ["name", "symbol", "tokenURI"]);
89
+ };
90
+ var tokenTypes = async (provider, address) => {
91
+ const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)]);
102
92
  const result = [];
103
93
  if (erc721) {
104
94
  result.push("ERC721");
@@ -107,11 +97,11 @@ var tokenTypes = /* @__PURE__ */ __name(async (provider, address) => {
107
97
  result.push("ERC1155");
108
98
  }
109
99
  return result;
110
- }, "tokenTypes");
100
+ };
111
101
 
112
102
  // src/lib/getNftMetadata.ts
113
103
  var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
114
- var getNftMetadata = /* @__PURE__ */ __name(async (contractAddress, provider, tokenId, load = false, defaultUri) => {
104
+ var getNftMetadata = async (contractAddress, provider, tokenId, load = false, defaultUri) => {
115
105
  const storage721 = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(contractAddress, provider);
116
106
  const storage1155 = import_open_zeppelin_typechain2.ERC1155URIStorage__factory.connect(contractAddress, provider);
117
107
  let uri721 = void 0;
@@ -144,9 +134,7 @@ var getNftMetadata = /* @__PURE__ */ __name(async (contractAddress, provider, to
144
134
  }
145
135
  } else {
146
136
  let checkedMetaDataUri;
147
- const axios = new import_axios.AxiosJson({
148
- timeout: 5e3
149
- });
137
+ const axios = new import_axios.AxiosJson({ timeout: 5e3 });
150
138
  try {
151
139
  if (tokenMetadataUri && tokenMetadataUri.length > 0) {
152
140
  checkedMetaDataUri = tokenMetadataUri ? (0, import_witness_blockchain_abstract.checkIpfsUrl)(tokenMetadataUri, ipfsGateway) : tokenMetadataUri;
@@ -160,34 +148,26 @@ var getNftMetadata = /* @__PURE__ */ __name(async (contractAddress, provider, to
160
148
  }
161
149
  }
162
150
  }
163
- return [
164
- tokenMetadataUri,
165
- metadata
166
- ];
167
- }, "getNftMetadata");
151
+ return [tokenMetadataUri, metadata];
152
+ };
168
153
 
169
154
  // src/lib/getNftsFromWalletFromOpenSea.ts
170
155
  var import_assert2 = require("@xylabs/assert");
171
156
  var import_axios2 = require("@xylabs/axios");
172
- var getNftsFromWalletFromOpenSea = /* @__PURE__ */ __name(async (address, maxNfts = 200, timeout = 2e3) => {
157
+ var getNftsFromWalletFromOpenSea = async (address, maxNfts = 200, timeout = 2e3) => {
173
158
  const apiKey = (0, import_assert2.assertEx)(process.env.OPENSEA_API_KEY, () => "No opensea key found");
174
- const axios = new import_axios2.AxiosJson({
175
- headers: {
176
- "x-api-key": apiKey
177
- },
178
- timeout
179
- });
159
+ const axios = new import_axios2.AxiosJson({ headers: { "x-api-key": apiKey }, timeout });
180
160
  const nfts = (await axios.get(`https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts?limit=${maxNfts}`)).data.nfts;
181
161
  return nfts;
182
- }, "getNftsFromWalletFromOpenSea");
162
+ };
183
163
 
184
164
  // src/lib/getProvider.ts
185
- var getProvider = /* @__PURE__ */ __name((providers) => {
165
+ var getProvider = (providers) => {
186
166
  return providers[Date.now() % providers.length];
187
- }, "getProvider");
167
+ };
188
168
 
189
169
  // src/lib/tryCall.ts
190
- var tryCall = /* @__PURE__ */ __name(async (func, name) => {
170
+ var tryCall = async (func, name) => {
191
171
  try {
192
172
  return await func();
193
173
  } catch (ex) {
@@ -197,13 +177,11 @@ var tryCall = /* @__PURE__ */ __name(async (func, name) => {
197
177
  }
198
178
  return void 0;
199
179
  }
200
- }, "tryCall");
180
+ };
201
181
 
202
182
  // src/lib/getNftsOwnedByAddress.ts
203
- var tokenTypeCache = new import_lru_cache.LRUCache({
204
- max: 100
205
- });
206
- var getTokenTypes = /* @__PURE__ */ __name(async (provider, address) => {
183
+ var tokenTypeCache = new import_lru_cache.LRUCache({ max: 100 });
184
+ var getTokenTypes = async (provider, address) => {
207
185
  const key = `${address}|${(await provider.getNetwork()).chainId}`;
208
186
  const currentValue = tokenTypeCache.get(key);
209
187
  if (currentValue) {
@@ -213,103 +191,98 @@ var getTokenTypes = /* @__PURE__ */ __name(async (provider, address) => {
213
191
  tokenTypeCache.set(key, types);
214
192
  return types;
215
193
  }
216
- }, "getTokenTypes");
217
- var getErc721MetadataUri = /* @__PURE__ */ __name(async (address, tokenId, provider) => {
194
+ };
195
+ var getErc721MetadataUri = async (address, tokenId, provider) => {
218
196
  try {
219
197
  const contract = import_open_zeppelin_typechain3.ERC721__factory.connect(address, provider);
220
- return [
221
- await contract.tokenURI(tokenId),
222
- void 0
223
- ];
198
+ return [await contract.tokenURI(tokenId), void 0];
224
199
  } catch (ex) {
225
- return [
226
- void 0,
227
- ex
228
- ];
200
+ return [void 0, ex];
229
201
  }
230
- }, "getErc721MetadataUri");
231
- var getErc1155MetadataUri = /* @__PURE__ */ __name(async (address, tokenId, provider) => {
202
+ };
203
+ var getErc1155MetadataUri = async (address, tokenId, provider) => {
232
204
  try {
233
205
  const contract = import_open_zeppelin_typechain3.ERC1155__factory.connect(address, provider);
234
- return [
235
- await contract.uri(tokenId),
236
- void 0
237
- ];
206
+ return [await contract.uri(tokenId), void 0];
238
207
  } catch (ex) {
239
- return [
240
- void 0,
241
- ex
242
- ];
208
+ return [void 0, ex];
243
209
  }
244
- }, "getErc1155MetadataUri");
245
- var getNftMetadataUri = /* @__PURE__ */ __name(async (address, tokenId, provider) => {
246
- const results = await Promise.all([
247
- getErc721MetadataUri(address, tokenId, provider),
248
- getErc1155MetadataUri(address, tokenId, provider)
249
- ]);
210
+ };
211
+ var getNftMetadataUri = async (address, tokenId, provider) => {
212
+ const results = await Promise.all([getErc721MetadataUri(address, tokenId, provider), getErc1155MetadataUri(address, tokenId, provider)]);
250
213
  return results[0][0] ?? results[1][0];
251
- }, "getNftMetadataUri");
252
- var getNftsOwnedByAddressWithMetadata = /* @__PURE__ */ __name(async (publicAddress, providers, maxNfts = 200, timeout = 5e3) => {
214
+ };
215
+ var getNftsOwnedByAddressWithMetadata = async (publicAddress, providers, maxNfts = 200, timeout = 5e3) => {
253
216
  const nfts = await getNftsOwnedByAddress(publicAddress, providers, maxNfts, timeout);
254
- const nftResult = await Promise.all(nfts.map(async (nft) => {
255
- try {
256
- if (!nft.metadataUri || !nft.metadata) {
257
- const [metadataUri, metadata] = await getNftMetadata(nft.implementation ?? nft.address, getProvider(providers), nft.tokenId, true, nft.metadataUri);
258
- nft.metadata = nft.metadata ?? metadata;
259
- nft.metadataUri = nft.metadataUri ?? metadataUri;
217
+ const nftResult = await Promise.all(
218
+ nfts.map(async (nft) => {
219
+ try {
220
+ if (!nft.metadataUri || !nft.metadata) {
221
+ const [metadataUri, metadata] = await getNftMetadata(
222
+ nft.implementation ?? nft.address,
223
+ getProvider(providers),
224
+ nft.tokenId,
225
+ true,
226
+ nft.metadataUri
227
+ );
228
+ nft.metadata = nft.metadata ?? metadata;
229
+ nft.metadataUri = nft.metadataUri ?? metadataUri;
230
+ }
231
+ return nft;
232
+ } catch (ex) {
233
+ const error = ex;
234
+ console.error(`Error: ${error.message}`);
235
+ console.error(`${error.stack}`);
236
+ throw ex;
260
237
  }
261
- return nft;
262
- } catch (ex) {
263
- const error = ex;
264
- console.error(`Error: ${error.message}`);
265
- console.error(`${error.stack}`);
266
- throw ex;
267
- }
268
- }));
238
+ })
239
+ );
269
240
  return nftResult;
270
- }, "getNftsOwnedByAddressWithMetadata");
271
- var getNftsOwnedByAddress = /* @__PURE__ */ __name(async (publicAddress, providers, maxNfts = 100, timeout = 5e3) => {
241
+ };
242
+ var getNftsOwnedByAddress = async (publicAddress, providers, maxNfts = 100, timeout = 5e3) => {
272
243
  const nfts = await getNftsFromWalletFromOpenSea(publicAddress, maxNfts, timeout);
273
- const nftResult = await Promise.all(nfts.map(async (nft) => {
274
- try {
275
- const { contract, identifier, metadata_url } = nft;
276
- const provider = getProvider(providers);
277
- const block = await provider.getBlockNumber();
278
- const [erc1967Status, erc1822Status] = await Promise.all([
279
- // Check if ERC-1967 Upgradeable
280
- (0, import_erc1967_witness.getErc1967SlotStatus)(provider, contract, block),
281
- // Check if ERC-1822 Upgradeable
282
- (0, import_erc1822_witness.getErc1822SlotStatus)(provider, contract, block)
283
- ]);
284
- const implementation = !erc1967Status.slots.implementation || (0, import_hex.isHexZero)(erc1967Status.slots.implementation) ? erc1822Status.implementation : erc1967Status.implementation;
285
- let supply = 1n;
286
- const types = await getTokenTypes(provider, implementation);
287
- if (types.includes("ERC1155")) {
288
- const supply1155 = import_open_zeppelin_typechain3.ERC1155Supply__factory.connect(implementation, getProvider(providers));
289
- supply = await tryCall(async () => await supply1155["totalSupply(uint256)"](erc1967Status.address)) ?? 1n;
290
- }
291
- const fields = {
292
- address: contract,
293
- chainId: Number((await provider.getNetwork()).chainId),
294
- metadataUri: metadata_url ?? void 0,
295
- supply: `0x${supply.toString(16)}`,
296
- tokenId: identifier,
297
- type: types.at(0),
298
- types
299
- };
300
- if (implementation !== contract) {
301
- fields.implementation = implementation;
244
+ const nftResult = await Promise.all(
245
+ nfts.map(async (nft) => {
246
+ try {
247
+ const { contract, identifier, metadata_url } = nft;
248
+ const provider = getProvider(providers);
249
+ const block = await provider.getBlockNumber();
250
+ const [erc1967Status, erc1822Status] = await Promise.all([
251
+ // Check if ERC-1967 Upgradeable
252
+ (0, import_erc1967_witness.getErc1967SlotStatus)(provider, contract, block),
253
+ // Check if ERC-1822 Upgradeable
254
+ (0, import_erc1822_witness.getErc1822SlotStatus)(provider, contract, block)
255
+ ]);
256
+ const implementation = !erc1967Status.slots.implementation || (0, import_hex.isHexZero)(erc1967Status.slots.implementation) ? erc1822Status.implementation : erc1967Status.implementation;
257
+ let supply = 1n;
258
+ const types = await getTokenTypes(provider, implementation);
259
+ if (types.includes("ERC1155")) {
260
+ const supply1155 = import_open_zeppelin_typechain3.ERC1155Supply__factory.connect(implementation, getProvider(providers));
261
+ supply = await tryCall(async () => await supply1155["totalSupply(uint256)"](erc1967Status.address)) ?? 1n;
262
+ }
263
+ const fields = {
264
+ address: contract,
265
+ chainId: Number((await provider.getNetwork()).chainId),
266
+ metadataUri: metadata_url ?? void 0,
267
+ supply: `0x${supply.toString(16)}`,
268
+ tokenId: identifier,
269
+ type: types.at(0),
270
+ types
271
+ };
272
+ if (implementation !== contract) {
273
+ fields.implementation = implementation;
274
+ }
275
+ return fields;
276
+ } catch (ex) {
277
+ const error = ex;
278
+ console.error(`Error: ${error.message}`);
279
+ console.error(`${error.stack}`);
280
+ throw ex;
302
281
  }
303
- return fields;
304
- } catch (ex) {
305
- const error = ex;
306
- console.error(`Error: ${error.message}`);
307
- console.error(`${error.stack}`);
308
- throw ex;
309
- }
310
- }));
282
+ })
283
+ );
311
284
  return nftResult;
312
- }, "getNftsOwnedByAddress");
285
+ };
313
286
 
314
287
  // src/Plugin.ts
315
288
  var import_crypto_nft_payload_plugin2 = require("@xyo-network/crypto-nft-payload-plugin");
@@ -324,13 +297,7 @@ var import_witness_evm_abstract = require("@xyo-network/witness-evm-abstract");
324
297
  var schema = import_crypto_nft_payload_plugin.NftSchema;
325
298
  var defaultMaxNfts = 200;
326
299
  var CryptoWalletNftWitness = class extends import_witness_evm_abstract.AbstractEvmWitness {
327
- static {
328
- __name(this, "CryptoWalletNftWitness");
329
- }
330
- static configSchemas = [
331
- ...super.configSchemas,
332
- import_crypto_nft_payload_plugin.NftWitnessConfigSchema
333
- ];
300
+ static configSchemas = [...super.configSchemas, import_crypto_nft_payload_plugin.NftWitnessConfigSchema];
334
301
  static defaultConfigSchema = import_crypto_nft_payload_plugin.NftWitnessConfigSchema;
335
302
  get loadMetadata() {
336
303
  return this.config.loadMetadata ?? true;
@@ -343,28 +310,27 @@ var CryptoWalletNftWitness = class extends import_witness_evm_abstract.AbstractE
343
310
  const queries = payloads?.filter(import_crypto_nft_payload_plugin.isNftWitnessQuery) ?? [];
344
311
  const providers = await this.getProviders();
345
312
  try {
346
- const observations = await Promise.all(queries.map(async (query) => {
347
- const provider = await this.getProvider(true, true);
348
- const addressValue = (0, import_assert3.assertEx)(query?.address ?? this.config.address, () => "params.address is required");
349
- const parsedAddressValue = import_eth_address.EthAddress.parse(addressValue);
350
- const address = (0, import_assert3.assertEx)(parsedAddressValue?.toString(), () => "Failed to parse params.address");
351
- const network = await provider.getNetwork();
352
- const chainId = (0, import_assert3.assertEx)(network.chainId, () => "params.chainId is required");
353
- const maxNfts = query?.maxNfts || defaultMaxNfts;
354
- try {
355
- const nfts = this.loadMetadata ? await getNftsOwnedByAddressWithMetadata(address, providers, maxNfts, this.timeout) : await getNftsOwnedByAddress(address, providers, maxNfts, this.timeout);
356
- const observation = nfts.map((nft) => {
357
- return {
358
- ...nft,
359
- schema
360
- };
361
- });
362
- return observation;
363
- } catch (ex) {
364
- const error = ex;
365
- throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}: ${error.message}`);
366
- }
367
- }));
313
+ const observations = await Promise.all(
314
+ queries.map(async (query) => {
315
+ const provider = await this.getProvider(true, true);
316
+ const addressValue = (0, import_assert3.assertEx)(query?.address ?? this.config.address, () => "params.address is required");
317
+ const parsedAddressValue = import_eth_address.EthAddress.parse(addressValue);
318
+ const address = (0, import_assert3.assertEx)(parsedAddressValue?.toString(), () => "Failed to parse params.address");
319
+ const network = await provider.getNetwork();
320
+ const chainId = (0, import_assert3.assertEx)(network.chainId, () => "params.chainId is required");
321
+ const maxNfts = query?.maxNfts || defaultMaxNfts;
322
+ try {
323
+ const nfts = this.loadMetadata ? await getNftsOwnedByAddressWithMetadata(address, providers, maxNfts, this.timeout) : await getNftsOwnedByAddress(address, providers, maxNfts, this.timeout);
324
+ const observation = nfts.map((nft) => {
325
+ return { ...nft, schema };
326
+ });
327
+ return observation;
328
+ } catch (ex) {
329
+ const error = ex;
330
+ throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}: ${error.message}`);
331
+ }
332
+ })
333
+ );
368
334
  return observations.flat();
369
335
  } catch (ex) {
370
336
  const error = ex;
@@ -375,15 +341,13 @@ var CryptoWalletNftWitness = class extends import_witness_evm_abstract.AbstractE
375
341
  };
376
342
 
377
343
  // src/Plugin.ts
378
- var CryptoWalletNftWitnessPlugin = /* @__PURE__ */ __name(() => (0, import_payloadset_plugin.createPayloadSetWitnessPlugin)({
379
- required: {
380
- [import_crypto_nft_payload_plugin2.NftSchema]: 1
381
- },
382
- schema: import_payload_model.PayloadSetSchema
383
- }, {
384
- witness: /* @__PURE__ */ __name(async (params) => {
385
- const result = await CryptoWalletNftWitness.create(params);
386
- return result;
387
- }, "witness")
388
- }), "CryptoWalletNftWitnessPlugin");
344
+ var CryptoWalletNftWitnessPlugin = () => (0, import_payloadset_plugin.createPayloadSetWitnessPlugin)(
345
+ { required: { [import_crypto_nft_payload_plugin2.NftSchema]: 1 }, schema: import_payload_model.PayloadSetSchema },
346
+ {
347
+ witness: async (params) => {
348
+ const result = await CryptoWalletNftWitness.create(params);
349
+ return result;
350
+ }
351
+ }
352
+ );
389
353
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/lib/contractHasFunctions.ts","../../src/lib/getNftsOwnedByAddress.ts","../../src/lib/getNftMetadata.ts","../../src/lib/tokenTypes.ts","../../src/lib/getNftsFromWalletFromOpenSea.ts","../../src/lib/getProvider.ts","../../src/lib/tryCall.ts","../../src/Plugin.ts","../../src/Witness.ts"],"sourcesContent":["export * from './lib/index.ts'\n// eslint-disable-next-line import/no-default-export\nexport { CryptoWalletNftWitnessPlugin, CryptoWalletNftWitnessPlugin as default } from './Plugin.ts'\nexport * from './Witness.ts'\n","import { assertEx } from '@xylabs/assert'\nimport { Interface, Provider } from 'ethers'\n\nexport const contractHasFunctions = async (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => {\n try {\n const bytecode = await provider.getCode(address, 'latest')\n for (const functionName of functionNames) {\n const selector = assertEx(contractInterface.getFunction(functionName)?.selector, () => 'Function not found on interface')\n if (!bytecode.includes(selector.slice(2))) {\n return false\n }\n return true\n }\n return false\n } catch (ex) {\n const error = ex as Error\n console.log(error)\n return false\n }\n}\n","import { isHexZero } from '@xylabs/hex'\nimport { NftInfoFields, TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { getErc1822SlotStatus } from '@xyo-network/erc1822-witness'\nimport { getErc1967SlotStatus } from '@xyo-network/erc1967-witness'\nimport { ERC721__factory, ERC1155__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { Provider } from 'ethers'\nimport { LRUCache } from 'lru-cache'\n\nimport { getNftMetadata } from './getNftMetadata.ts'\nimport { getNftsFromWalletFromOpenSea } from './getNftsFromWalletFromOpenSea.ts'\nimport { getProvider } from './getProvider.ts'\nimport { tokenTypes } from './tokenTypes.ts'\nimport { tryCall } from './tryCall.ts'\n\nconst tokenTypeCache = new LRUCache<string, TokenType[]>({ max: 100 })\n\nexport const getTokenTypes = async (provider: Provider, address: string) => {\n const key = `${address}|${(await provider.getNetwork()).chainId}`\n const currentValue = tokenTypeCache.get(key)\n if (currentValue) {\n return currentValue\n } else {\n const types = await tokenTypes(provider, address)\n tokenTypeCache.set(key, types)\n return types\n }\n}\n\nexport const getErc721MetadataUri = async (\n address: string,\n tokenId: string,\n provider: Provider,\n): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC721__factory.connect(address, provider)\n return [await contract.tokenURI(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getErc1155MetadataUri = async (\n address: string,\n tokenId: string,\n provider: Provider,\n): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC1155__factory.connect(address, provider)\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, provider: Provider) => {\n const results = await Promise.all([getErc721MetadataUri(address, tokenId, provider), getErc1155MetadataUri(address, tokenId, provider)])\n return results[0][0] ?? results[1][0]\n}\n\nexport const getNftsOwnedByAddressWithMetadata = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param provider The provider to use for accessing the block chain */\n providers: Provider[],\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 200,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 5000,\n): Promise<NftInfoFields[]> => {\n const nfts = await getNftsOwnedByAddress(publicAddress, providers, maxNfts, timeout)\n const nftResult = await Promise.all(\n nfts.map(async (nft) => {\n try {\n if (!nft.metadataUri || !nft.metadata) {\n const [metadataUri, metadata] = await getNftMetadata(\n nft.implementation ?? nft.address,\n getProvider(providers),\n nft.tokenId,\n true,\n nft.metadataUri,\n )\n nft.metadata = nft.metadata ?? metadata\n nft.metadataUri = nft.metadataUri ?? metadataUri\n }\n return nft\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 return nftResult\n}\n\nexport const getNftsOwnedByAddress = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param provider The provider to use for accessing the block chain */\n providers: Provider[],\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 100,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 5000,\n): Promise<NftInfoFields[]> => {\n // const assets = await getAssetsFromWallet(publicAddress, maxNfts, timeout)\n const nfts = await getNftsFromWalletFromOpenSea(publicAddress, maxNfts, timeout)\n\n const nftResult = await Promise.all(\n nfts.map(async (nft) => {\n try {\n const { contract, identifier, metadata_url } = nft\n const provider = getProvider(providers)\n\n const block = await provider.getBlockNumber()\n\n // Check if Upgradeable\n const [erc1967Status, erc1822Status] = await Promise.all([\n // Check if ERC-1967 Upgradeable\n getErc1967SlotStatus(provider, contract, block),\n\n // Check if ERC-1822 Upgradeable\n getErc1822SlotStatus(provider, contract, block),\n ])\n\n const implementation\n = !erc1967Status.slots.implementation || isHexZero(erc1967Status.slots.implementation)\n ? erc1822Status.implementation\n : erc1967Status.implementation\n\n let supply = 1n\n const types = await getTokenTypes(provider, implementation)\n if (types.includes('ERC1155')) {\n const supply1155 = ERC1155Supply__factory.connect(implementation, getProvider(providers))\n supply = (await tryCall(async () => await supply1155['totalSupply(uint256)'](erc1967Status.address))) ?? 1n\n }\n const fields: NftInfoFields = {\n address: contract,\n chainId: Number((await provider.getNetwork()).chainId),\n metadataUri: metadata_url ?? undefined,\n supply: `0x${supply.toString(16)}`,\n tokenId: identifier,\n type: types.at(0),\n types,\n }\n if (implementation !== contract) {\n fields.implementation = implementation\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","/* eslint-disable complexity */\n\nimport { AxiosJson } from '@xylabs/axios'\nimport { NftMetadata } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721URIStorage__factory, ERC1155URIStorage__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { checkIpfsUrl } from '@xyo-network/witness-blockchain-abstract'\nimport { Provider } from 'ethers'\nimport parseDataUrl from 'parse-data-url'\n\nimport { isErc721, isErc1155 } from './tokenTypes.ts'\n\n/* const baseUrlAbi = [\n {\n inputs: [],\n name: 'baseUrl',\n outputs: [\n {\n internalType: 'string',\n name: '',\n type: 'string',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n] */\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\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: Provider,\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 load = false,\n defaultUri?: string,\n): Promise<[string | undefined, NftMetadata | undefined]> => {\n const storage721 = ERC721URIStorage__factory.connect(contractAddress, provider)\n const storage1155 = ERC1155URIStorage__factory.connect(contractAddress, provider)\n\n let uri721: string | undefined = undefined\n const is721 = await isErc721(provider, contractAddress)\n if (is721) {\n try {\n uri721 = await storage721.tokenURI(tokenId)\n } catch {\n // const error = ex as Error\n // console.error(`metaDataUri[${error.name}][${contractAddress}]: storage721.tokenURI(tokenId) failed`)\n }\n }\n\n /* let baseUrl: string | undefined = undefined\n if (is721) {\n try {\n const baseUrlContract = new Contract(contractAddress, baseUrlAbi, provider)\n baseUrl = await baseUrlContract.bareUrl()\n } catch (ex) {\n const error = ex as Error\n console.error(`baseUrl[${error.name}][${contractAddress}]: baseUrl() failed`)\n }\n }\n\n if (baseUrl && !uri721?.startsWith(baseUrl)) {\n uri721 = `${baseUrl}${uri721 ?? tokenId}`\n }\n */\n\n let uri1155: string | undefined = undefined\n if (!uri721) {\n const is1155 = await isErc1155(provider, contractAddress)\n if (is1155) {\n try {\n uri1155 = await storage1155.uri(tokenId)\n } catch {\n // const error = ex as Error\n // console.error(`metaDataUri[${error.name}][${contractAddress}]: storage1155.uri(tokenId) failed`)\n // console.log(error.message)\n }\n }\n }\n\n const tokenMetadataUri = uri721 || uri1155 || defaultUri\n let metadata: NftMetadata | undefined = undefined\n if (load) {\n if (tokenMetadataUri?.startsWith('data:')) {\n const parsedDataUrl = parseDataUrl(tokenMetadataUri)\n if (parsedDataUrl !== false && parsedDataUrl.contentType === 'application/json') {\n const buf = parsedDataUrl.toBuffer()\n const value = buf.toString('utf8')\n metadata = JSON.parse(value)\n }\n } else {\n let checkedMetaDataUri: string | undefined\n /* if (tokenMetadataUri && tokenMetadataUri.length < 5) {\n console.log(`tokenMetadataUri [<5][${contractAddress}]: ${tokenMetadataUri}`)\n console.log(`tokenMetadataUri [uri721]: ${uri721}`)\n console.log(`tokenMetadataUri [uri1155]: ${uri1155}`)\n console.log(`tokenMetadataUri [defaultUri]: ${defaultUri}`)\n } */\n const axios = new AxiosJson({ timeout: 5000 })\n try {\n if (tokenMetadataUri && tokenMetadataUri.length > 0) {\n checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri\n }\n metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : undefined\n } catch {\n try {\n metadata = defaultUri ? (await axios.get(defaultUri)).data : undefined\n } catch {\n // const error = ex as Error\n // console.error(`metadata: ${error.message}`)\n }\n }\n }\n }\n\n return [tokenMetadataUri, metadata]\n}\n","import { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC1155URIStorage__factory, IERC721Metadata__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { Provider } from 'ethers'\n\nimport { contractHasFunctions } from './contractHasFunctions.ts'\n\nexport const isErc1155 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, ERC1155URIStorage__factory.createInterface(), ['uri'])\n}\n\nexport const isErc721 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, IERC721Metadata__factory.createInterface(), ['name', 'symbol', 'tokenURI'])\n}\n\nexport const tokenTypes = async (provider: Provider, address: string) => {\n const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)])\n const result: TokenType[] = []\n if (erc721) {\n result.push('ERC721')\n }\n if (erc1155) {\n result.push('ERC1155')\n }\n return result\n}\n","import { assertEx } from '@xylabs/assert'\nimport { AxiosJson } from '@xylabs/axios'\n\ninterface OpenSeaNFT {\n /*\n * Collection slug. A unique string to identify a collection on OpenSea\n */\n collection: string\n /*\n * The unique public blockchain identifier for the contract\n */\n contract: string\n /**\n * @deprecated\n */\n created_at: string\n /*\n * Description of the NFT\n */\n description: string | null\n /*\n * The NFT's unique identifier within the smart contract (also referred to as token_id)\n */\n identifier: string\n /*\n * Link to the image associated with the NFT\n */\n image_url: string | null\n /*\n * If the item is currently able to be bought or sold using OpenSea\n */\n is_disabled: boolean\n /*\n * If the item is currently classified as 'Not Safe for Work' by OpenSea as defined in OpenSea's NSFW Policy.\n */\n is_nsfw: boolean\n /*\n * Link to the offchain metadata store\n */\n metadata_url: string | null\n /*\n * Name of the NFT\n */\n name: string | null\n /*\n * ERC standard of the token (erc721, erc1155)\n */\n token_standard: string\n /*\n * Last time that the NFT's metadata was updated by OpenSea\n */\n updated_at: string\n}\n\nexport const getNftsFromWalletFromOpenSea = async (address: string, maxNfts = 200, timeout = 2000) => {\n const apiKey = assertEx(process.env.OPENSEA_API_KEY, () => 'No opensea key found')\n\n const axios = new AxiosJson({ headers: { 'x-api-key': apiKey }, timeout })\n\n const nfts = (await axios.get<{ nfts: OpenSeaNFT[] }>(`https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts?limit=${maxNfts}`)).data\n .nfts\n return nfts\n}\n","import { Provider } from 'ethers'\n\nexport const getProvider = (providers: Provider[]) => {\n return providers[Date.now() % providers.length] // pick a random provider\n}\n","export const tryCall = async <T>(func: () => Promise<T>, name?: string): Promise<T | undefined> => {\n try {\n return await func()\n } catch (ex) {\n if (name) {\n const error = ex as Error\n console.log(`tryCall failed [${name}]: ${error.message}`)\n }\n return undefined\n }\n}\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin, PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoWalletNftWitness } from './Witness.ts'\n\nexport const CryptoWalletNftWitnessPlugin = (): PayloadSetWitnessPlugin<CryptoWalletNftWitness> =>\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 {\n CryptoWalletNftWitnessConfig,\n isNftWitnessQuery,\n NftInfo,\n NftSchema,\n NftWitnessConfigSchema,\n NftWitnessQuery,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { Schema } from '@xyo-network/payload-model'\nimport { AbstractEvmWitness, EvmWitnessParams } from '@xyo-network/witness-evm-abstract'\n\nimport { getNftsOwnedByAddress, getNftsOwnedByAddressWithMetadata } from './lib/index.ts'\n\nexport type CryptoWalletNftWitnessParams = EvmWitnessParams<CryptoWalletNftWitnessConfig>\n\nconst schema = NftSchema\n\nconst defaultMaxNfts = 200\n\nexport class CryptoWalletNftWitness<TParams extends CryptoWalletNftWitnessParams = CryptoWalletNftWitnessParams> extends AbstractEvmWitness<\n TParams,\n NftWitnessQuery,\n NftInfo\n> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, NftWitnessConfigSchema]\n static override readonly defaultConfigSchema: Schema = NftWitnessConfigSchema\n\n get loadMetadata() {\n return this.config.loadMetadata ?? true\n }\n\n get timeout() {\n return this.config.timeout ?? 10_000\n }\n\n protected override async observeHandler(payloads?: NftWitnessQuery[]): Promise<NftInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftWitnessQuery) ?? []\n // calling it here to make sure we rests the cache\n const providers = await this.getProviders()\n try {\n const observations = await Promise.all(\n queries.map(async (query) => {\n const provider = await this.getProvider(true, true)\n const addressValue = assertEx(query?.address ?? this.config.address, () => 'params.address is required')\n const parsedAddressValue = EthAddress.parse(addressValue)\n const address = assertEx(parsedAddressValue?.toString(), () => 'Failed to parse params.address')\n const network = await provider.getNetwork()\n const chainId = assertEx(network.chainId, () => 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n try {\n const nfts\n = this.loadMetadata\n ? await getNftsOwnedByAddressWithMetadata(address, providers, maxNfts, this.timeout)\n : await getNftsOwnedByAddress(address, providers, maxNfts, this.timeout)\n const observation = nfts.map<NftInfo>((nft) => {\n return { ...nft, schema }\n })\n return observation\n } catch (ex) {\n const error = ex as Error\n throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}: ${error.message}`)\n }\n }),\n )\n return observations.flat()\n } catch (ex) {\n const error = ex as Error\n console.error(error)\n return []\n }\n }\n}\n"],"mappings":"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","names":["contractHasFunctions","provider","address","contractInterface","functionNames","bytecode","getCode","functionName","selector","assertEx","getFunction","includes","slice","ex","error","console","log","import_open_zeppelin_typechain","import_open_zeppelin_typechain","isErc1155","provider","address","contractHasFunctions","ERC1155URIStorage__factory","createInterface","isErc721","IERC721Metadata__factory","tokenTypes","erc721","erc1155","Promise","all","result","push","ipfsGateway","getNftMetadata","contractAddress","provider","tokenId","load","defaultUri","storage721","ERC721URIStorage__factory","connect","storage1155","ERC1155URIStorage__factory","uri721","undefined","is721","isErc721","tokenURI","uri1155","is1155","isErc1155","uri","tokenMetadataUri","metadata","startsWith","parsedDataUrl","parseDataUrl","contentType","buf","toBuffer","value","toString","JSON","parse","checkedMetaDataUri","axios","AxiosJson","timeout","length","checkIpfsUrl","get","data","import_assert","import_axios","getNftsFromWalletFromOpenSea","address","maxNfts","timeout","apiKey","assertEx","process","env","OPENSEA_API_KEY","axios","AxiosJson","headers","nfts","get","data","getProvider","providers","Date","now","length","tryCall","func","name","ex","error","console","log","message","undefined","tokenTypeCache","LRUCache","max","getTokenTypes","provider","address","key","getNetwork","chainId","currentValue","get","types","tokenTypes","set","getErc721MetadataUri","tokenId","contract","ERC721__factory","connect","tokenURI","undefined","ex","getErc1155MetadataUri","ERC1155__factory","uri","getNftMetadataUri","results","Promise","all","getNftsOwnedByAddressWithMetadata","publicAddress","providers","maxNfts","timeout","nfts","getNftsOwnedByAddress","nftResult","map","nft","metadataUri","metadata","getNftMetadata","implementation","getProvider","error","console","message","stack","getNftsFromWalletFromOpenSea","identifier","metadata_url","block","getBlockNumber","erc1967Status","erc1822Status","getErc1967SlotStatus","getErc1822SlotStatus","slots","isHexZero","supply","includes","supply1155","ERC1155Supply__factory","tryCall","fields","Number","toString","type","at","import_crypto_nft_payload_plugin","import_assert","schema","NftSchema","defaultMaxNfts","CryptoWalletNftWitness","AbstractEvmWitness","configSchemas","NftWitnessConfigSchema","defaultConfigSchema","loadMetadata","config","timeout","observeHandler","payloads","started","queries","filter","isNftWitnessQuery","providers","getProviders","observations","Promise","all","map","query","provider","getProvider","addressValue","assertEx","address","parsedAddressValue","EthAddress","parse","toString","network","getNetwork","chainId","maxNfts","nfts","getNftsOwnedByAddressWithMetadata","getNftsOwnedByAddress","observation","nft","ex","error","Error","message","flat","console","CryptoWalletNftWitnessPlugin","createPayloadSetWitnessPlugin","required","NftSchema","schema","PayloadSetSchema","witness","params","result","CryptoWalletNftWitness","create"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/lib/contractHasFunctions.ts","../../src/lib/getNftsOwnedByAddress.ts","../../src/lib/getNftMetadata.ts","../../src/lib/tokenTypes.ts","../../src/lib/getNftsFromWalletFromOpenSea.ts","../../src/lib/getProvider.ts","../../src/lib/tryCall.ts","../../src/Plugin.ts","../../src/Witness.ts"],"sourcesContent":["export * from './lib/index.ts'\n// eslint-disable-next-line import/no-default-export\nexport { CryptoWalletNftWitnessPlugin, CryptoWalletNftWitnessPlugin as default } from './Plugin.ts'\nexport * from './Witness.ts'\n","import { assertEx } from '@xylabs/assert'\nimport { Interface, Provider } from 'ethers'\n\nexport const contractHasFunctions = async (provider: Provider, address: string, contractInterface: Interface, functionNames: string[]) => {\n try {\n const bytecode = await provider.getCode(address, 'latest')\n for (const functionName of functionNames) {\n const selector = assertEx(contractInterface.getFunction(functionName)?.selector, () => 'Function not found on interface')\n if (!bytecode.includes(selector.slice(2))) {\n return false\n }\n return true\n }\n return false\n } catch (ex) {\n const error = ex as Error\n console.log(error)\n return false\n }\n}\n","import { isHexZero } from '@xylabs/hex'\nimport { NftInfoFields, TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { getErc1822SlotStatus } from '@xyo-network/erc1822-witness'\nimport { getErc1967SlotStatus } from '@xyo-network/erc1967-witness'\nimport { ERC721__factory, ERC1155__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { Provider } from 'ethers'\nimport { LRUCache } from 'lru-cache'\n\nimport { getNftMetadata } from './getNftMetadata.ts'\nimport { getNftsFromWalletFromOpenSea } from './getNftsFromWalletFromOpenSea.ts'\nimport { getProvider } from './getProvider.ts'\nimport { tokenTypes } from './tokenTypes.ts'\nimport { tryCall } from './tryCall.ts'\n\nconst tokenTypeCache = new LRUCache<string, TokenType[]>({ max: 100 })\n\nexport const getTokenTypes = async (provider: Provider, address: string) => {\n const key = `${address}|${(await provider.getNetwork()).chainId}`\n const currentValue = tokenTypeCache.get(key)\n if (currentValue) {\n return currentValue\n } else {\n const types = await tokenTypes(provider, address)\n tokenTypeCache.set(key, types)\n return types\n }\n}\n\nexport const getErc721MetadataUri = async (\n address: string,\n tokenId: string,\n provider: Provider,\n): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC721__factory.connect(address, provider)\n return [await contract.tokenURI(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getErc1155MetadataUri = async (\n address: string,\n tokenId: string,\n provider: Provider,\n): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC1155__factory.connect(address, provider)\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, provider: Provider) => {\n const results = await Promise.all([getErc721MetadataUri(address, tokenId, provider), getErc1155MetadataUri(address, tokenId, provider)])\n return results[0][0] ?? results[1][0]\n}\n\nexport const getNftsOwnedByAddressWithMetadata = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param provider The provider to use for accessing the block chain */\n providers: Provider[],\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 200,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 5000,\n): Promise<NftInfoFields[]> => {\n const nfts = await getNftsOwnedByAddress(publicAddress, providers, maxNfts, timeout)\n const nftResult = await Promise.all(\n nfts.map(async (nft) => {\n try {\n if (!nft.metadataUri || !nft.metadata) {\n const [metadataUri, metadata] = await getNftMetadata(\n nft.implementation ?? nft.address,\n getProvider(providers),\n nft.tokenId,\n true,\n nft.metadataUri,\n )\n nft.metadata = nft.metadata ?? metadata\n nft.metadataUri = nft.metadataUri ?? metadataUri\n }\n return nft\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 return nftResult\n}\n\nexport const getNftsOwnedByAddress = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param provider The provider to use for accessing the block chain */\n providers: Provider[],\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 100,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 5000,\n): Promise<NftInfoFields[]> => {\n // const assets = await getAssetsFromWallet(publicAddress, maxNfts, timeout)\n const nfts = await getNftsFromWalletFromOpenSea(publicAddress, maxNfts, timeout)\n\n const nftResult = await Promise.all(\n nfts.map(async (nft) => {\n try {\n const { contract, identifier, metadata_url } = nft\n const provider = getProvider(providers)\n\n const block = await provider.getBlockNumber()\n\n // Check if Upgradeable\n const [erc1967Status, erc1822Status] = await Promise.all([\n // Check if ERC-1967 Upgradeable\n getErc1967SlotStatus(provider, contract, block),\n\n // Check if ERC-1822 Upgradeable\n getErc1822SlotStatus(provider, contract, block),\n ])\n\n const implementation\n = !erc1967Status.slots.implementation || isHexZero(erc1967Status.slots.implementation)\n ? erc1822Status.implementation\n : erc1967Status.implementation\n\n let supply = 1n\n const types = await getTokenTypes(provider, implementation)\n if (types.includes('ERC1155')) {\n const supply1155 = ERC1155Supply__factory.connect(implementation, getProvider(providers))\n supply = (await tryCall(async () => await supply1155['totalSupply(uint256)'](erc1967Status.address))) ?? 1n\n }\n const fields: NftInfoFields = {\n address: contract,\n chainId: Number((await provider.getNetwork()).chainId),\n metadataUri: metadata_url ?? undefined,\n supply: `0x${supply.toString(16)}`,\n tokenId: identifier,\n type: types.at(0),\n types,\n }\n if (implementation !== contract) {\n fields.implementation = implementation\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","/* eslint-disable complexity */\n\nimport { AxiosJson } from '@xylabs/axios'\nimport { NftMetadata } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721URIStorage__factory, ERC1155URIStorage__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { checkIpfsUrl } from '@xyo-network/witness-blockchain-abstract'\nimport { Provider } from 'ethers'\nimport parseDataUrl from 'parse-data-url'\n\nimport { isErc721, isErc1155 } from './tokenTypes.ts'\n\n/* const baseUrlAbi = [\n {\n inputs: [],\n name: 'baseUrl',\n outputs: [\n {\n internalType: 'string',\n name: '',\n type: 'string',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n] */\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\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: Provider,\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 load = false,\n defaultUri?: string,\n): Promise<[string | undefined, NftMetadata | undefined]> => {\n const storage721 = ERC721URIStorage__factory.connect(contractAddress, provider)\n const storage1155 = ERC1155URIStorage__factory.connect(contractAddress, provider)\n\n let uri721: string | undefined = undefined\n const is721 = await isErc721(provider, contractAddress)\n if (is721) {\n try {\n uri721 = await storage721.tokenURI(tokenId)\n } catch {\n // const error = ex as Error\n // console.error(`metaDataUri[${error.name}][${contractAddress}]: storage721.tokenURI(tokenId) failed`)\n }\n }\n\n /* let baseUrl: string | undefined = undefined\n if (is721) {\n try {\n const baseUrlContract = new Contract(contractAddress, baseUrlAbi, provider)\n baseUrl = await baseUrlContract.bareUrl()\n } catch (ex) {\n const error = ex as Error\n console.error(`baseUrl[${error.name}][${contractAddress}]: baseUrl() failed`)\n }\n }\n\n if (baseUrl && !uri721?.startsWith(baseUrl)) {\n uri721 = `${baseUrl}${uri721 ?? tokenId}`\n }\n */\n\n let uri1155: string | undefined = undefined\n if (!uri721) {\n const is1155 = await isErc1155(provider, contractAddress)\n if (is1155) {\n try {\n uri1155 = await storage1155.uri(tokenId)\n } catch {\n // const error = ex as Error\n // console.error(`metaDataUri[${error.name}][${contractAddress}]: storage1155.uri(tokenId) failed`)\n // console.log(error.message)\n }\n }\n }\n\n const tokenMetadataUri = uri721 || uri1155 || defaultUri\n let metadata: NftMetadata | undefined = undefined\n if (load) {\n if (tokenMetadataUri?.startsWith('data:')) {\n const parsedDataUrl = parseDataUrl(tokenMetadataUri)\n if (parsedDataUrl !== false && parsedDataUrl.contentType === 'application/json') {\n const buf = parsedDataUrl.toBuffer()\n const value = buf.toString('utf8')\n metadata = JSON.parse(value)\n }\n } else {\n let checkedMetaDataUri: string | undefined\n /* if (tokenMetadataUri && tokenMetadataUri.length < 5) {\n console.log(`tokenMetadataUri [<5][${contractAddress}]: ${tokenMetadataUri}`)\n console.log(`tokenMetadataUri [uri721]: ${uri721}`)\n console.log(`tokenMetadataUri [uri1155]: ${uri1155}`)\n console.log(`tokenMetadataUri [defaultUri]: ${defaultUri}`)\n } */\n const axios = new AxiosJson({ timeout: 5000 })\n try {\n if (tokenMetadataUri && tokenMetadataUri.length > 0) {\n checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri\n }\n metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : undefined\n } catch {\n try {\n metadata = defaultUri ? (await axios.get(defaultUri)).data : undefined\n } catch {\n // const error = ex as Error\n // console.error(`metadata: ${error.message}`)\n }\n }\n }\n }\n\n return [tokenMetadataUri, metadata]\n}\n","import { TokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC1155URIStorage__factory, IERC721Metadata__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { Provider } from 'ethers'\n\nimport { contractHasFunctions } from './contractHasFunctions.ts'\n\nexport const isErc1155 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, ERC1155URIStorage__factory.createInterface(), ['uri'])\n}\n\nexport const isErc721 = async (provider: Provider, address: string) => {\n return await contractHasFunctions(provider, address, IERC721Metadata__factory.createInterface(), ['name', 'symbol', 'tokenURI'])\n}\n\nexport const tokenTypes = async (provider: Provider, address: string) => {\n const [erc721, erc1155] = await Promise.all([isErc721(provider, address), isErc1155(provider, address)])\n const result: TokenType[] = []\n if (erc721) {\n result.push('ERC721')\n }\n if (erc1155) {\n result.push('ERC1155')\n }\n return result\n}\n","import { assertEx } from '@xylabs/assert'\nimport { AxiosJson } from '@xylabs/axios'\n\ninterface OpenSeaNFT {\n /*\n * Collection slug. A unique string to identify a collection on OpenSea\n */\n collection: string\n /*\n * The unique public blockchain identifier for the contract\n */\n contract: string\n /**\n * @deprecated\n */\n created_at: string\n /*\n * Description of the NFT\n */\n description: string | null\n /*\n * The NFT's unique identifier within the smart contract (also referred to as token_id)\n */\n identifier: string\n /*\n * Link to the image associated with the NFT\n */\n image_url: string | null\n /*\n * If the item is currently able to be bought or sold using OpenSea\n */\n is_disabled: boolean\n /*\n * If the item is currently classified as 'Not Safe for Work' by OpenSea as defined in OpenSea's NSFW Policy.\n */\n is_nsfw: boolean\n /*\n * Link to the offchain metadata store\n */\n metadata_url: string | null\n /*\n * Name of the NFT\n */\n name: string | null\n /*\n * ERC standard of the token (erc721, erc1155)\n */\n token_standard: string\n /*\n * Last time that the NFT's metadata was updated by OpenSea\n */\n updated_at: string\n}\n\nexport const getNftsFromWalletFromOpenSea = async (address: string, maxNfts = 200, timeout = 2000) => {\n const apiKey = assertEx(process.env.OPENSEA_API_KEY, () => 'No opensea key found')\n\n const axios = new AxiosJson({ headers: { 'x-api-key': apiKey }, timeout })\n\n const nfts = (await axios.get<{ nfts: OpenSeaNFT[] }>(`https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts?limit=${maxNfts}`)).data\n .nfts\n return nfts\n}\n","import { Provider } from 'ethers'\n\nexport const getProvider = (providers: Provider[]) => {\n return providers[Date.now() % providers.length] // pick a random provider\n}\n","export const tryCall = async <T>(func: () => Promise<T>, name?: string): Promise<T | undefined> => {\n try {\n return await func()\n } catch (ex) {\n if (name) {\n const error = ex as Error\n console.log(`tryCall failed [${name}]: ${error.message}`)\n }\n return undefined\n }\n}\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin, PayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoWalletNftWitness } from './Witness.ts'\n\nexport const CryptoWalletNftWitnessPlugin = (): PayloadSetWitnessPlugin<CryptoWalletNftWitness> =>\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 {\n CryptoWalletNftWitnessConfig,\n isNftWitnessQuery,\n NftInfo,\n NftSchema,\n NftWitnessConfigSchema,\n NftWitnessQuery,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { Schema } from '@xyo-network/payload-model'\nimport { AbstractEvmWitness, EvmWitnessParams } from '@xyo-network/witness-evm-abstract'\n\nimport { getNftsOwnedByAddress, getNftsOwnedByAddressWithMetadata } from './lib/index.ts'\n\nexport type CryptoWalletNftWitnessParams = EvmWitnessParams<CryptoWalletNftWitnessConfig>\n\nconst schema = NftSchema\n\nconst defaultMaxNfts = 200\n\nexport class CryptoWalletNftWitness<TParams extends CryptoWalletNftWitnessParams = CryptoWalletNftWitnessParams> extends AbstractEvmWitness<\n TParams,\n NftWitnessQuery,\n NftInfo\n> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, NftWitnessConfigSchema]\n static override readonly defaultConfigSchema: Schema = NftWitnessConfigSchema\n\n get loadMetadata() {\n return this.config.loadMetadata ?? true\n }\n\n get timeout() {\n return this.config.timeout ?? 10_000\n }\n\n protected override async observeHandler(payloads?: NftWitnessQuery[]): Promise<NftInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftWitnessQuery) ?? []\n // calling it here to make sure we rests the cache\n const providers = await this.getProviders()\n try {\n const observations = await Promise.all(\n queries.map(async (query) => {\n const provider = await this.getProvider(true, true)\n const addressValue = assertEx(query?.address ?? this.config.address, () => 'params.address is required')\n const parsedAddressValue = EthAddress.parse(addressValue)\n const address = assertEx(parsedAddressValue?.toString(), () => 'Failed to parse params.address')\n const network = await provider.getNetwork()\n const chainId = assertEx(network.chainId, () => 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n try {\n const nfts\n = this.loadMetadata\n ? await getNftsOwnedByAddressWithMetadata(address, providers, maxNfts, this.timeout)\n : await getNftsOwnedByAddress(address, providers, maxNfts, this.timeout)\n const observation = nfts.map<NftInfo>((nft) => {\n return { ...nft, schema }\n })\n return observation\n } catch (ex) {\n const error = ex as Error\n throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}: ${error.message}`)\n }\n }),\n )\n return observations.flat()\n } catch (ex) {\n const error = ex as Error\n console.error(error)\n return []\n }\n }\n}\n"],"mappings":"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","names":["import_open_zeppelin_typechain","import_open_zeppelin_typechain","parseDataUrl","import_assert","import_axios","import_crypto_nft_payload_plugin","import_assert"]}