@metamask-previews/assets-controllers 27.2.0-preview-07ab424 → 27.2.0-preview-a8ffe8e

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 (88) hide show
  1. package/dist/AssetsContractController.js +6 -6
  2. package/dist/AssetsContractController.mjs +5 -5
  3. package/dist/NftController.js +3 -5
  4. package/dist/NftController.mjs +2 -4
  5. package/dist/NftDetectionController.js +4 -4
  6. package/dist/NftDetectionController.mjs +3 -3
  7. package/dist/Standards/ERC20Standard.js +3 -3
  8. package/dist/Standards/ERC20Standard.mjs +2 -2
  9. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js +3 -3
  10. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.mjs +2 -2
  11. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js +3 -3
  12. package/dist/Standards/NftStandards/ERC721/ERC721Standard.mjs +2 -2
  13. package/dist/TokenDetectionController.js +3 -3
  14. package/dist/TokenDetectionController.mjs +2 -2
  15. package/dist/TokenListController.js +4 -4
  16. package/dist/TokenListController.mjs +3 -3
  17. package/dist/TokenRatesController.js +3 -3
  18. package/dist/TokenRatesController.mjs +2 -2
  19. package/dist/TokensController.js +6 -6
  20. package/dist/TokensController.mjs +5 -5
  21. package/dist/assetsUtil.js +2 -8
  22. package/dist/assetsUtil.mjs +1 -7
  23. package/dist/{chunk-6NO7Z5DL.js → chunk-3PHIUBM3.js} +4 -4
  24. package/dist/{chunk-KCUSDOIE.mjs → chunk-4OXWUHJZ.mjs} +4 -4
  25. package/dist/{chunk-355MWUUQ.js → chunk-BM7EPTR6.js} +3 -3
  26. package/dist/{chunk-VY7TUOK2.js → chunk-D3N35ABH.js} +3 -3
  27. package/dist/{chunk-RELRWIJN.js → chunk-D6BDJYSK.js} +2 -68
  28. package/dist/chunk-D6BDJYSK.js.map +1 -0
  29. package/dist/{chunk-NUBQRDKI.js → chunk-E2SLNUD4.js} +11 -11
  30. package/dist/{chunk-VHCPQS4X.js → chunk-GCWWC4X3.js} +5 -5
  31. package/dist/{chunk-KRTEFV4Q.mjs → chunk-IURNPMBB.mjs} +2 -2
  32. package/dist/{chunk-WSOHBBCO.js → chunk-JEGLHDNA.js} +42 -56
  33. package/dist/chunk-JEGLHDNA.js.map +1 -0
  34. package/dist/{chunk-GLZ66IRX.mjs → chunk-KDMDWUVX.mjs} +41 -55
  35. package/dist/chunk-KDMDWUVX.mjs.map +1 -0
  36. package/dist/{chunk-MQ7TIWBK.mjs → chunk-KS4MOA2T.mjs} +2 -2
  37. package/dist/{chunk-XEZJ5XMV.js → chunk-LBPVKXXG.js} +5 -5
  38. package/dist/{chunk-CEENXWOB.mjs → chunk-N5H5KDJZ.mjs} +2 -2
  39. package/dist/{chunk-25YSNHCK.mjs → chunk-NHX4QGOD.mjs} +2 -2
  40. package/dist/{chunk-AQIXUBTK.js → chunk-NIXK7RMZ.js} +74 -127
  41. package/dist/chunk-NIXK7RMZ.js.map +1 -0
  42. package/dist/{chunk-KSGMD24G.js → chunk-Q6TLNHYC.js} +7 -7
  43. package/dist/{chunk-523YP4Z3.mjs → chunk-QQAG6ECS.mjs} +3 -3
  44. package/dist/{chunk-OE2USEN3.js → chunk-RUPB4ELK.js} +4 -4
  45. package/dist/{chunk-4YU7CT4O.js → chunk-UWALRJ7V.js} +7 -7
  46. package/dist/{chunk-WIVSZVF4.mjs → chunk-XNVBYRLY.mjs} +2 -2
  47. package/dist/{chunk-ZKJSG4TA.mjs → chunk-XSFM6BLC.mjs} +2 -2
  48. package/dist/{chunk-IFJWX5RY.mjs → chunk-YJNCY2LB.mjs} +74 -127
  49. package/dist/chunk-YJNCY2LB.mjs.map +1 -0
  50. package/dist/{chunk-76KGJJJV.mjs → chunk-ZM42FNAQ.mjs} +5 -5
  51. package/dist/{chunk-E5PIGGYR.mjs → chunk-ZPAX2HLQ.mjs} +1 -67
  52. package/dist/chunk-ZPAX2HLQ.mjs.map +1 -0
  53. package/dist/index.js +13 -13
  54. package/dist/index.mjs +16 -16
  55. package/dist/token-service.js +3 -3
  56. package/dist/token-service.mjs +2 -2
  57. package/dist/tsconfig.build.tsbuildinfo +1 -1
  58. package/dist/types/NftController.d.ts +12 -87
  59. package/dist/types/NftController.d.ts.map +1 -1
  60. package/dist/types/NftDetectionController.d.ts +184 -0
  61. package/dist/types/NftDetectionController.d.ts.map +1 -1
  62. package/dist/types/assetsUtil.d.ts +1 -21
  63. package/dist/types/assetsUtil.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/chunk-AQIXUBTK.js.map +0 -1
  66. package/dist/chunk-E5PIGGYR.mjs.map +0 -1
  67. package/dist/chunk-GLZ66IRX.mjs.map +0 -1
  68. package/dist/chunk-IFJWX5RY.mjs.map +0 -1
  69. package/dist/chunk-RELRWIJN.js.map +0 -1
  70. package/dist/chunk-WSOHBBCO.js.map +0 -1
  71. /package/dist/{chunk-6NO7Z5DL.js.map → chunk-3PHIUBM3.js.map} +0 -0
  72. /package/dist/{chunk-KCUSDOIE.mjs.map → chunk-4OXWUHJZ.mjs.map} +0 -0
  73. /package/dist/{chunk-355MWUUQ.js.map → chunk-BM7EPTR6.js.map} +0 -0
  74. /package/dist/{chunk-VY7TUOK2.js.map → chunk-D3N35ABH.js.map} +0 -0
  75. /package/dist/{chunk-NUBQRDKI.js.map → chunk-E2SLNUD4.js.map} +0 -0
  76. /package/dist/{chunk-VHCPQS4X.js.map → chunk-GCWWC4X3.js.map} +0 -0
  77. /package/dist/{chunk-KRTEFV4Q.mjs.map → chunk-IURNPMBB.mjs.map} +0 -0
  78. /package/dist/{chunk-MQ7TIWBK.mjs.map → chunk-KS4MOA2T.mjs.map} +0 -0
  79. /package/dist/{chunk-XEZJ5XMV.js.map → chunk-LBPVKXXG.js.map} +0 -0
  80. /package/dist/{chunk-CEENXWOB.mjs.map → chunk-N5H5KDJZ.mjs.map} +0 -0
  81. /package/dist/{chunk-25YSNHCK.mjs.map → chunk-NHX4QGOD.mjs.map} +0 -0
  82. /package/dist/{chunk-KSGMD24G.js.map → chunk-Q6TLNHYC.js.map} +0 -0
  83. /package/dist/{chunk-523YP4Z3.mjs.map → chunk-QQAG6ECS.mjs.map} +0 -0
  84. /package/dist/{chunk-OE2USEN3.js.map → chunk-RUPB4ELK.js.map} +0 -0
  85. /package/dist/{chunk-4YU7CT4O.js.map → chunk-UWALRJ7V.js.map} +0 -0
  86. /package/dist/{chunk-WIVSZVF4.mjs.map → chunk-XNVBYRLY.mjs.map} +0 -0
  87. /package/dist/{chunk-ZKJSG4TA.mjs.map → chunk-XSFM6BLC.mjs.map} +0 -0
  88. /package/dist/{chunk-76KGJJJV.mjs.map → chunk-ZM42FNAQ.mjs.map} +0 -0
@@ -1,17 +1,17 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
2
 
3
- var _chunkVHCPQS4Xjs = require('./chunk-VHCPQS4X.js');
3
+ var _chunkGCWWC4X3js = require('./chunk-GCWWC4X3.js');
4
4
 
5
5
 
6
- var _chunk355MWUUQjs = require('./chunk-355MWUUQ.js');
6
+ var _chunkBM7EPTR6js = require('./chunk-BM7EPTR6.js');
7
7
 
8
8
 
9
9
 
10
- var _chunkVY7TUOK2js = require('./chunk-VY7TUOK2.js');
10
+ var _chunkD3N35ABHjs = require('./chunk-D3N35ABH.js');
11
11
 
12
12
 
13
13
 
14
- var _chunkRELRWIJNjs = require('./chunk-RELRWIJN.js');
14
+ var _chunkD6BDJYSKjs = require('./chunk-D6BDJYSK.js');
15
15
 
16
16
  // src/TokensController.ts
17
17
  var _contracts = require('@ethersproject/contracts');
@@ -135,14 +135,14 @@ var TokensController = class extends _basecontroller.BaseControllerV1 {
135
135
  */
136
136
  async fetchTokenMetadata(tokenAddress) {
137
137
  try {
138
- const token = await _chunkVY7TUOK2js.fetchTokenMetadata.call(void 0,
138
+ const token = await _chunkD3N35ABHjs.fetchTokenMetadata.call(void 0,
139
139
  this.config.chainId,
140
140
  tokenAddress,
141
141
  this.abortController.signal
142
142
  );
143
143
  return token;
144
144
  } catch (error) {
145
- if (error instanceof Error && error.message.includes(_chunkVY7TUOK2js.TOKEN_METADATA_NO_SUPPORT_ERROR)) {
145
+ if (error instanceof Error && error.message.includes(_chunkD3N35ABHjs.TOKEN_METADATA_NO_SUPPORT_ERROR)) {
146
146
  return void 0;
147
147
  }
148
148
  throw error;
@@ -202,12 +202,12 @@ var TokensController = class extends _basecontroller.BaseControllerV1 {
202
202
  address,
203
203
  symbol,
204
204
  decimals,
205
- image: image || _chunkRELRWIJNjs.formatIconUrlWithProxy.call(void 0, {
205
+ image: image || _chunkD6BDJYSKjs.formatIconUrlWithProxy.call(void 0, {
206
206
  chainId: currentChainId,
207
207
  tokenAddress: address
208
208
  }),
209
209
  isERC721,
210
- aggregators: _chunkRELRWIJNjs.formatAggregatorNames.call(void 0, tokenMetadata?.aggregators || []),
210
+ aggregators: _chunkD6BDJYSKjs.formatAggregatorNames.call(void 0, tokenMetadata?.aggregators || []),
211
211
  name
212
212
  };
213
213
  const previousIndex = newTokens.findIndex(
@@ -532,7 +532,7 @@ var TokensController = class extends _basecontroller.BaseControllerV1 {
532
532
  }
533
533
  const provider = this._getProvider(networkClientId);
534
534
  const isErc1155 = await _controllerutils.safelyExecute.call(void 0,
535
- () => new (0, _chunkVHCPQS4Xjs.ERC1155Standard)(provider).contractSupportsBase1155Interface(
535
+ () => new (0, _chunkGCWWC4X3js.ERC1155Standard)(provider).contractSupportsBase1155Interface(
536
536
  asset.address
537
537
  )
538
538
  );
@@ -541,7 +541,7 @@ var TokensController = class extends _basecontroller.BaseControllerV1 {
541
541
  `Contract ${asset.address} must match type ${type}, but was detected as ${_controllerutils.ERC1155}`
542
542
  );
543
543
  }
544
- const erc20 = new (0, _chunk355MWUUQjs.ERC20Standard)(provider);
544
+ const erc20 = new (0, _chunkBM7EPTR6js.ERC20Standard)(provider);
545
545
  const [contractName, contractSymbol, contractDecimals] = await Promise.all([
546
546
  _controllerutils.safelyExecute.call(void 0, () => erc20.getTokenName(asset.address)),
547
547
  _controllerutils.safelyExecute.call(void 0, () => erc20.getTokenSymbol(asset.address)),
@@ -701,4 +701,4 @@ var TokensController_default = TokensController;
701
701
 
702
702
 
703
703
  exports.getDefaultTokensState = getDefaultTokensState; exports.TokensController = TokensController; exports.TokensController_default = TokensController_default;
704
- //# sourceMappingURL=chunk-NUBQRDKI.js.map
704
+ //# sourceMappingURL=chunk-E2SLNUD4.js.map
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkRELRWIJNjs = require('./chunk-RELRWIJN.js');
4
+ var _chunkD6BDJYSKjs = require('./chunk-D6BDJYSK.js');
5
5
 
6
6
  // src/Standards/NftStandards/ERC1155/ERC1155Standard.ts
7
7
  var _contracts = require('@ethersproject/contracts');
@@ -73,7 +73,7 @@ var ERC1155Standard = class {
73
73
  async getBalanceOf(contractAddress, address, tokenId) {
74
74
  const contract = new (0, _contracts.Contract)(contractAddress, _metamaskethabis.abiERC1155, this.provider);
75
75
  const balance = await contract.balanceOf(address, tokenId);
76
- return _chunkRELRWIJNjs.ethersBigNumberToBN.call(void 0, balance);
76
+ return _chunkD6BDJYSKjs.ethersBigNumberToBN.call(void 0, balance);
77
77
  }
78
78
  /**
79
79
  * Transfer single ERC1155 token.
@@ -184,7 +184,7 @@ var ERC1155Standard = class {
184
184
  _controllerutils.safelyExecute.call(void 0, () => this.getAssetName(address)),
185
185
  tokenId ? _controllerutils.safelyExecute.call(void 0,
186
186
  () => this.getTokenURI(address, tokenId).then(
187
- (uri) => uri.startsWith("ipfs://") ? _chunkRELRWIJNjs.getFormattedIpfsUrl.call(void 0, ipfsGateway, uri, true) : uri
187
+ (uri) => uri.startsWith("ipfs://") ? _chunkD6BDJYSKjs.getFormattedIpfsUrl.call(void 0, ipfsGateway, uri, true) : uri
188
188
  )
189
189
  ) : void 0
190
190
  ]);
@@ -194,7 +194,7 @@ var ERC1155Standard = class {
194
194
  const object = await response.json();
195
195
  image = object?.image;
196
196
  if (image?.startsWith("ipfs://")) {
197
- image = _chunkRELRWIJNjs.getFormattedIpfsUrl.call(void 0, ipfsGateway, image, true);
197
+ image = _chunkD6BDJYSKjs.getFormattedIpfsUrl.call(void 0, ipfsGateway, image, true);
198
198
  }
199
199
  } catch {
200
200
  }
@@ -212,4 +212,4 @@ var ERC1155Standard = class {
212
212
 
213
213
 
214
214
  exports.ERC1155Standard = ERC1155Standard;
215
- //# sourceMappingURL=chunk-VHCPQS4X.js.map
215
+ //# sourceMappingURL=chunk-GCWWC4X3.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isTokenListSupportedForNetwork
3
- } from "./chunk-E5PIGGYR.mjs";
3
+ } from "./chunk-ZPAX2HLQ.mjs";
4
4
 
5
5
  // src/token-service.ts
6
6
  import { convertHexToDecimal, timeoutFetch } from "@metamask/controller-utils";
@@ -71,4 +71,4 @@ export {
71
71
  fetchTokenListByChainId,
72
72
  fetchTokenMetadata
73
73
  };
74
- //# sourceMappingURL=chunk-KRTEFV4Q.mjs.map
74
+ //# sourceMappingURL=chunk-IURNPMBB.mjs.map
@@ -1,10 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
- var _chunkRELRWIJNjs = require('./chunk-RELRWIJN.js');
4
-
5
- // src/NftDetectionController.ts
6
-
7
-
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/NftDetectionController.ts
8
2
 
9
3
 
10
4
 
@@ -13,6 +7,13 @@ var _chunkRELRWIJNjs = require('./chunk-RELRWIJN.js');
13
7
  var _controllerutils = require('@metamask/controller-utils');
14
8
  var _pollingcontroller = require('@metamask/polling-controller');
15
9
  var DEFAULT_INTERVAL = 18e4;
10
+ var BlockaidResultType = /* @__PURE__ */ ((BlockaidResultType2) => {
11
+ BlockaidResultType2["Benign"] = "Benign";
12
+ BlockaidResultType2["Spam"] = "Spam";
13
+ BlockaidResultType2["Warning"] = "Warning";
14
+ BlockaidResultType2["Malicious"] = "Malicious";
15
+ return BlockaidResultType2;
16
+ })(BlockaidResultType || {});
16
17
  var NftDetectionController = class extends _pollingcontroller.StaticIntervalPollingControllerV1 {
17
18
  /**
18
19
  * Creates an NftDetectionController instance.
@@ -88,7 +89,7 @@ var NftDetectionController = class extends _pollingcontroller.StaticIntervalPoll
88
89
  address,
89
90
  next
90
91
  }) {
91
- return `${_controllerutils.OPENSEA_PROXY_URL}/chain/${"ethereum" /* ethereum */}/account/${address}/nfts?limit=200&next=${next ?? ""}`;
92
+ return `${_controllerutils.NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=200&includeTopBid=true&continuation=${next ?? ""}`;
92
93
  }
93
94
  async getOwnerNfts(address) {
94
95
  let nftApiResponse;
@@ -97,32 +98,21 @@ var NftDetectionController = class extends _pollingcontroller.StaticIntervalPoll
97
98
  do {
98
99
  nftApiResponse = await _controllerutils.fetchWithErrorHandling.call(void 0, {
99
100
  url: this.getOwnerNftApi({ address, next }),
101
+ options: {
102
+ headers: {
103
+ Version: "1"
104
+ }
105
+ },
100
106
  timeout: 15e3
101
107
  });
102
108
  if (!nftApiResponse) {
103
109
  return nfts;
104
110
  }
105
- const newNfts = await Promise.all(
106
- nftApiResponse.nfts.map(async (nftV2) => {
107
- const nftV1 = _chunkRELRWIJNjs.mapOpenSeaNftV2ToV1.call(void 0, nftV2);
108
- if (!nftV1.image_url && nftV2.metadata_url) {
109
- const nftDetails = await _controllerutils.safelyExecute.call(void 0,
110
- () => _controllerutils.timeoutFetch.call(void 0,
111
- this.getNftApi({
112
- contractAddress: nftV2.contract,
113
- tokenId: nftV2.identifier
114
- }),
115
- void 0,
116
- 1e3
117
- ).then((r) => r.json())
118
- );
119
- nftV1.image_original_url = nftDetails?.nft?.image_url ?? null;
120
- }
121
- return nftV1;
122
- })
111
+ const newNfts = nftApiResponse.tokens.filter(
112
+ (elm) => elm.token.isSpam === false && (elm.blockaidResult?.result_type ? elm.blockaidResult?.result_type === "Benign" /* Benign */ : true)
123
113
  );
124
114
  nfts = [...nfts, ...newNfts];
125
- } while (next = nftApiResponse.next);
115
+ } while (next = nftApiResponse.continuation);
126
116
  return nfts;
127
117
  }
128
118
  async _executePoll(networkClientId, options) {
@@ -182,50 +172,45 @@ var NftDetectionController = class extends _pollingcontroller.StaticIntervalPoll
182
172
  const apiNfts = await this.getOwnerNfts(userAddress);
183
173
  const addNftPromises = apiNfts.map(async (nft) => {
184
174
  const {
185
- token_id,
186
- num_sales,
187
- background_color,
188
- image_url,
189
- image_preview_url,
190
- image_thumbnail_url,
191
- image_original_url,
192
- animation_url,
193
- animation_original_url,
175
+ tokenId: token_id,
176
+ contract,
177
+ kind,
178
+ image: image_url,
179
+ imageSmall: image_thumbnail_url,
180
+ metadata: { imageOriginal: image_original_url } = {},
194
181
  name,
195
182
  description,
196
- external_link,
197
- creator,
198
- asset_contract: { address, schema_name },
199
- last_sale
200
- } = nft;
183
+ attributes,
184
+ topBid,
185
+ lastSale,
186
+ rarityRank,
187
+ rarityScore,
188
+ collection
189
+ } = nft.token;
201
190
  let ignored;
202
191
  const { ignoredNfts } = this.getNftState();
203
192
  if (ignoredNfts.length) {
204
193
  ignored = ignoredNfts.find((c) => {
205
- return c.address === _controllerutils.toChecksumHexAddress.call(void 0, address) && c.tokenId === token_id;
194
+ return c.address === _controllerutils.toChecksumHexAddress.call(void 0, contract) && c.tokenId === token_id;
206
195
  });
207
196
  }
208
197
  if (!ignored) {
209
198
  const nftMetadata = Object.assign(
210
199
  {},
211
200
  { name },
212
- creator && { creator },
213
201
  description && { description },
214
202
  image_url && { image: image_url },
215
- num_sales && { numberOfSales: num_sales },
216
- background_color && { backgroundColor: background_color },
217
- image_preview_url && { imagePreview: image_preview_url },
218
203
  image_thumbnail_url && { imageThumbnail: image_thumbnail_url },
219
204
  image_original_url && { imageOriginal: image_original_url },
220
- animation_url && { animation: animation_url },
221
- animation_original_url && {
222
- animationOriginal: animation_original_url
223
- },
224
- schema_name && { standard: schema_name },
225
- external_link && { externalLink: external_link },
226
- last_sale && { lastSale: last_sale }
205
+ kind && { standard: kind.toUpperCase() },
206
+ lastSale && { lastSale },
207
+ attributes && { attributes },
208
+ topBid && { topBid },
209
+ rarityRank && { rarityRank },
210
+ rarityScore && { rarityScore },
211
+ collection && { collection }
227
212
  );
228
- await this.addNft(address, token_id, {
213
+ await this.addNft(contract, token_id, {
229
214
  nftMetadata,
230
215
  userAddress,
231
216
  source: "detected" /* Detected */,
@@ -241,5 +226,6 @@ var NftDetectionController_default = NftDetectionController;
241
226
 
242
227
 
243
228
 
244
- exports.NftDetectionController = NftDetectionController; exports.NftDetectionController_default = NftDetectionController_default;
245
- //# sourceMappingURL=chunk-WSOHBBCO.js.map
229
+
230
+ exports.BlockaidResultType = BlockaidResultType; exports.NftDetectionController = NftDetectionController; exports.NftDetectionController_default = NftDetectionController_default;
231
+ //# sourceMappingURL=chunk-JEGLHDNA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/NftDetectionController.ts"],"names":["BlockaidResultType"],"mappings":"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","sourcesContent":["import type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport {\n fetchWithErrorHandling,\n toChecksumHexAddress,\n ChainId,\n NFT_API_BASE_URL,\n} from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkController,\n NetworkState,\n NetworkClient,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { Source } from './constants';\nimport {\n type NftController,\n type NftState,\n type NftMetadata,\n} from './NftController';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * @type ApiNft\n *\n * NFT object coming from OpenSea api\n * @property token_id - The NFT identifier\n * @property num_sales - Number of sales\n * @property background_color - The background color to be displayed with the item\n * @property image_url - URI of an image associated with this NFT\n * @property image_preview_url - URI of a smaller image associated with this NFT\n * @property image_thumbnail_url - URI of a thumbnail image associated with this NFT\n * @property image_original_url - URI of the original image associated with this NFT\n * @property animation_url - URI of a animation associated with this NFT\n * @property animation_original_url - URI of the original animation associated with this NFT\n * @property name - The NFT name\n * @property description - The NFT description\n * @property external_link - External link containing additional information\n * @property assetContract - The NFT contract information object\n * @property creator - The NFT owner information object\n * @property lastSale - When this item was last sold\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNft {\n token_id: string;\n num_sales: number | null;\n background_color: string | null;\n image_url: string | null;\n image_preview_url: string | null;\n image_thumbnail_url: string | null;\n image_original_url: string | null;\n animation_url: string | null;\n animation_original_url: string | null;\n name: string | null;\n description: string | null;\n external_link: string | null;\n asset_contract: ApiNftContract;\n creator: ApiNftCreator;\n last_sale: ApiNftLastSale | null;\n}\n\n/**\n * @type ApiNftContract\n *\n * NFT contract object coming from OpenSea api\n * @property address - Address of the NFT contract\n * @property asset_contract_type - The NFT type, it could be `semi-fungible` or `non-fungible`\n * @property created_date - Creation date\n * @property collection - Object containing the contract name and URI of an image associated\n * @property schema_name - The schema followed by the contract, it could be `ERC721` or `ERC1155`\n * @property symbol - The NFT contract symbol\n * @property total_supply - Total supply of NFTs\n * @property description - The NFT contract description\n * @property external_link - External link containing additional information\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNftContract {\n address: string;\n asset_contract_type: string | null;\n created_date: string | null;\n schema_name: string | null;\n symbol: string | null;\n total_supply: string | null;\n description: string | null;\n external_link: string | null;\n collection: {\n name: string | null;\n image_url?: string | null;\n tokenCount?: string | null;\n };\n}\n\n/**\n * @type ApiNftLastSale\n *\n * NFT sale object coming from OpenSea api\n * @property event_timestamp - Object containing a `username`\n * @property total_price - URI of NFT image associated with this owner\n * @property transaction - Object containing transaction_hash and block_hash\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNftLastSale {\n event_timestamp: string;\n total_price: string;\n transaction: { transaction_hash: string; block_hash: string };\n}\n\n/**\n * @type ApiNftCreator\n *\n * NFT creator object coming from OpenSea api\n * @property user - Object containing a `username`\n * @property profile_img_url - URI of NFT image associated with this owner\n * @property address - The owner address\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNftCreator {\n user: { username: string };\n profile_img_url: string;\n address: string;\n}\n\n/**\n * @type NftDetectionConfig\n *\n * NftDetection configuration\n * @property interval - Polling interval used to fetch new token rates\n * @property chainId - Current chain ID\n * @property selectedAddress - Vault selected address\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface NftDetectionConfig extends BaseConfig {\n interval: number;\n chainId: Hex;\n selectedAddress: string;\n}\n\nexport type ReservoirResponse = {\n tokens: TokensResponse[];\n continuation?: string;\n};\n\nexport type TokensResponse = {\n token: TokenResponse;\n ownership: Ownership;\n market?: Market;\n blockaidResult?: Blockaid;\n};\n\nexport enum BlockaidResultType {\n Benign = 'Benign',\n Spam = 'Spam',\n Warning = 'Warning',\n Malicious = 'Malicious',\n}\n\nexport type Blockaid = {\n contract: string;\n chainId: number;\n result_type: BlockaidResultType;\n malicious_score: string;\n attack_types: object;\n};\n\nexport type Market = {\n floorAsk?: FloorAsk;\n topBid?: TopBid;\n};\n\nexport type TokenResponse = {\n chainId: number;\n contract: string;\n tokenId: string;\n kind?: string;\n name?: string;\n image?: string;\n imageSmall?: string;\n imageLarge?: string;\n metadata?: Metadata;\n description?: string;\n supply?: number;\n remainingSupply?: number;\n rarityScore?: number;\n rarity?: number;\n rarityRank?: number;\n media?: string;\n isFlagged?: boolean;\n isSpam?: boolean;\n isNsfw?: boolean;\n metadataDisabled?: boolean;\n lastFlagUpdate?: string;\n lastFlagChange?: string;\n collection?: Collection;\n lastSale?: LastSale;\n topBid?: TopBid;\n lastAppraisalValue?: number;\n attributes?: Attributes[];\n};\n\nexport type TopBid = {\n id?: string;\n price?: Price;\n source?: {\n id?: string;\n domain?: string;\n name?: string;\n icon?: string;\n url?: string;\n };\n};\n\nexport type LastSale = {\n saleId?: string;\n token?: {\n contract?: string;\n tokenId?: string;\n name?: string;\n image?: string;\n collection?: {\n id?: string;\n name?: string;\n };\n };\n orderSource?: string;\n orderSide?: 'ask' | 'bid';\n orderKind?: string;\n orderId?: string;\n from?: string;\n to?: string;\n amount?: string;\n fillSource?: string;\n block?: number;\n txHash?: string;\n logIndex?: number;\n batchIndex?: number;\n timestamp?: number;\n price?: Price;\n washTradingScore?: number;\n royaltyFeeBps?: number;\n marketplaceFeeBps?: number;\n paidFullRoyalty?: boolean;\n feeBreakdown?: FeeBreakdown[];\n isDeleted?: boolean;\n createdAt?: string;\n updatedAt?: string;\n};\n\nexport type FeeBreakdown = {\n kind?: string;\n bps?: number;\n recipient?: string;\n source?: string;\n rawAmount?: string;\n};\n\nexport type Attributes = {\n key?: string;\n kind?: string;\n value: string;\n tokenCount?: number;\n onSaleCount?: number;\n floorAskPrice?: Price | null;\n topBidValue?: number | null;\n createdAt?: string;\n};\n\nexport type Collection = {\n id?: string;\n name?: string;\n slug?: string;\n symbol?: string;\n imageUrl?: string;\n image?: string;\n isSpam?: boolean;\n isNsfw?: boolean;\n creator?: string;\n tokenCount?: string;\n metadataDisabled?: boolean;\n openseaVerificationStatus?: string;\n floorAskPrice?: Price;\n royaltiesBps?: number;\n royalties?: Royalties[];\n};\n\nexport type Royalties = {\n bps?: number;\n recipient?: string;\n};\n\nexport type Ownership = {\n tokenCount?: string;\n onSaleCount?: string;\n floorAsk?: FloorAsk;\n acquiredAt?: string;\n};\n\nexport type FloorAsk = {\n id?: string;\n price?: Price;\n maker?: string;\n kind?: string;\n validFrom?: number;\n validUntil?: number;\n source?: Source;\n rawData?: Metadata;\n isNativeOffChainCancellable?: boolean;\n};\n\nexport type Price = {\n currency?: {\n contract?: string;\n name?: string;\n symbol?: string;\n decimals?: number;\n chainId?: number;\n };\n amount?: {\n raw?: string;\n decimal?: number;\n usd?: number;\n native?: number;\n };\n netAmount?: {\n raw?: string;\n decimal?: number;\n usd?: number;\n native?: number;\n };\n};\n\nexport type Metadata = {\n imageOriginal?: string;\n tokenURI?: string;\n};\n\n/**\n * Controller that passively polls on a set interval for NFT auto detection\n */\nexport class NftDetectionController extends StaticIntervalPollingControllerV1<\n NftDetectionConfig,\n BaseState\n> {\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private getOwnerNftApi({\n address,\n next,\n }: {\n address: string;\n next?: string;\n }) {\n return `${NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=200&includeTopBid=true&continuation=${\n next ?? ''\n }`;\n }\n\n private async getOwnerNfts(address: string) {\n let nftApiResponse: ReservoirResponse;\n let nfts: TokensResponse[] = [];\n let next;\n\n do {\n nftApiResponse = await fetchWithErrorHandling({\n url: this.getOwnerNftApi({ address, next }),\n options: {\n headers: {\n Version: '1',\n },\n },\n timeout: 15000,\n });\n\n if (!nftApiResponse) {\n return nfts;\n }\n\n const newNfts = nftApiResponse.tokens.filter(\n (elm) =>\n elm.token.isSpam === false &&\n (elm.blockaidResult?.result_type\n ? elm.blockaidResult?.result_type === BlockaidResultType.Benign\n : true),\n );\n\n nfts = [...nfts, ...newNfts];\n } while ((next = nftApiResponse.continuation));\n\n return nfts;\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'NftDetectionController';\n\n private readonly getOpenSeaApiKey: () => string | undefined;\n\n private readonly addNft: NftController['addNft'];\n\n private readonly getNftApi: NftController['getNftApi'];\n\n private readonly getNftState: () => NftState;\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n /**\n * Creates an NftDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNftsStateChange - Allows subscribing to assets controller state changes.\n * @param options.onPreferencesStateChange - Allows subscribing to preferences controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param options.getOpenSeaApiKey - Gets the OpenSea API key, if one is set.\n * @param options.addNft - Add an NFT.\n * @param options.getNftApi - Gets the URL to fetch an NFT from OpenSea.\n * @param options.getNftState - Gets the current state of the Assets controller.\n * @param options.getNetworkClientById - Gets the network client by ID, from the NetworkController.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n chainId: initialChainId,\n getNetworkClientById,\n onPreferencesStateChange,\n onNetworkStateChange,\n getOpenSeaApiKey,\n addNft,\n getNftApi,\n getNftState,\n }: {\n chainId: Hex;\n getNetworkClientById: NetworkController['getNetworkClientById'];\n onNftsStateChange: (listener: (nftsState: NftState) => void) => void;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getOpenSeaApiKey: () => string | undefined;\n addNft: NftController['addNft'];\n getNftApi: NftController['getNftApi'];\n getNftState: () => NftState;\n },\n config?: Partial<NftDetectionConfig>,\n state?: Partial<BaseState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: DEFAULT_INTERVAL,\n chainId: initialChainId,\n selectedAddress: '',\n disabled: true,\n };\n this.initialize();\n this.getNftState = getNftState;\n this.getNetworkClientById = getNetworkClientById;\n onPreferencesStateChange(({ selectedAddress, useNftDetection }) => {\n const { selectedAddress: previouslySelectedAddress, disabled } =\n this.config;\n\n if (\n selectedAddress !== previouslySelectedAddress ||\n !useNftDetection !== disabled\n ) {\n this.configure({ selectedAddress, disabled: !useNftDetection });\n if (useNftDetection) {\n this.start();\n } else {\n this.stop();\n }\n }\n });\n\n onNetworkStateChange(({ providerConfig }) => {\n this.configure({\n chainId: providerConfig.chainId,\n });\n });\n this.getOpenSeaApiKey = getOpenSeaApiKey;\n this.addNft = addNft;\n this.getNftApi = getNftApi;\n this.setIntervalLength(this.config.interval);\n }\n\n async _executePoll(\n networkClientId: string,\n options: { address: string },\n ): Promise<void> {\n await this.detectNfts({ networkClientId, userAddress: options.address });\n }\n\n /**\n * Start polling for the currency rate.\n */\n async start() {\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n\n await this.startPolling();\n }\n\n /**\n * Stop polling for the currency rate.\n */\n stop() {\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - An interval on which to poll.\n */\n private async startPolling(interval?: number): Promise<void> {\n interval && this.configure({ interval }, false, false);\n this.stopPolling();\n await this.detectNfts();\n this.intervalId = setInterval(async () => {\n await this.detectNfts();\n }, this.config.interval);\n }\n\n /**\n * Checks whether network is mainnet or not.\n *\n * @returns Whether current network is mainnet.\n */\n isMainnet = (): boolean => this.config.chainId === ChainId.mainnet;\n\n isMainnetByNetworkClientId = (networkClient: NetworkClient): boolean => {\n return networkClient.configuration.chainId === ChainId.mainnet;\n };\n\n /**\n * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are\n * added.\n *\n * @param options - Options bag.\n * @param options.networkClientId - The network client ID to detect NFTs on.\n * @param options.userAddress - The address to detect NFTs for.\n */\n async detectNfts(\n {\n networkClientId,\n userAddress,\n }: {\n networkClientId?: NetworkClientId;\n userAddress: string;\n } = { userAddress: this.config.selectedAddress },\n ) {\n /* istanbul ignore if */\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n /* istanbul ignore else */\n if (!userAddress) {\n return;\n }\n\n const apiNfts = await this.getOwnerNfts(userAddress);\n const addNftPromises = apiNfts.map(async (nft) => {\n const {\n tokenId: token_id,\n contract,\n kind,\n image: image_url,\n imageSmall: image_thumbnail_url,\n metadata: { imageOriginal: image_original_url } = {},\n name,\n description,\n attributes,\n topBid,\n lastSale,\n rarityRank,\n rarityScore,\n collection,\n } = nft.token;\n\n let ignored;\n /* istanbul ignore else */\n const { ignoredNfts } = this.getNftState();\n if (ignoredNfts.length) {\n ignored = ignoredNfts.find((c) => {\n /* istanbul ignore next */\n return (\n c.address === toChecksumHexAddress(contract) &&\n c.tokenId === token_id\n );\n });\n }\n\n /* istanbul ignore else */\n if (!ignored) {\n /* istanbul ignore next */\n const nftMetadata: NftMetadata = Object.assign(\n {},\n { name },\n description && { description },\n image_url && { image: image_url },\n image_thumbnail_url && { imageThumbnail: image_thumbnail_url },\n image_original_url && { imageOriginal: image_original_url },\n kind && { standard: kind.toUpperCase() },\n lastSale && { lastSale },\n attributes && { attributes },\n topBid && { topBid },\n rarityRank && { rarityRank },\n rarityScore && { rarityScore },\n collection && { collection },\n );\n\n await this.addNft(contract, token_id, {\n nftMetadata,\n userAddress,\n source: Source.Detected,\n networkClientId,\n });\n }\n });\n await Promise.all(addNftPromises);\n }\n}\n\nexport default NftDetectionController;\n"]}
@@ -1,18 +1,19 @@
1
- import {
2
- mapOpenSeaNftV2ToV1
3
- } from "./chunk-E5PIGGYR.mjs";
4
-
5
1
  // src/NftDetectionController.ts
6
2
  import {
7
- OPENSEA_PROXY_URL,
8
3
  fetchWithErrorHandling,
9
4
  toChecksumHexAddress,
10
5
  ChainId,
11
- timeoutFetch,
12
- safelyExecute
6
+ NFT_API_BASE_URL
13
7
  } from "@metamask/controller-utils";
14
8
  import { StaticIntervalPollingControllerV1 } from "@metamask/polling-controller";
15
9
  var DEFAULT_INTERVAL = 18e4;
10
+ var BlockaidResultType = /* @__PURE__ */ ((BlockaidResultType2) => {
11
+ BlockaidResultType2["Benign"] = "Benign";
12
+ BlockaidResultType2["Spam"] = "Spam";
13
+ BlockaidResultType2["Warning"] = "Warning";
14
+ BlockaidResultType2["Malicious"] = "Malicious";
15
+ return BlockaidResultType2;
16
+ })(BlockaidResultType || {});
16
17
  var NftDetectionController = class extends StaticIntervalPollingControllerV1 {
17
18
  /**
18
19
  * Creates an NftDetectionController instance.
@@ -88,7 +89,7 @@ var NftDetectionController = class extends StaticIntervalPollingControllerV1 {
88
89
  address,
89
90
  next
90
91
  }) {
91
- return `${OPENSEA_PROXY_URL}/chain/${"ethereum" /* ethereum */}/account/${address}/nfts?limit=200&next=${next ?? ""}`;
92
+ return `${NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=200&includeTopBid=true&continuation=${next ?? ""}`;
92
93
  }
93
94
  async getOwnerNfts(address) {
94
95
  let nftApiResponse;
@@ -97,32 +98,21 @@ var NftDetectionController = class extends StaticIntervalPollingControllerV1 {
97
98
  do {
98
99
  nftApiResponse = await fetchWithErrorHandling({
99
100
  url: this.getOwnerNftApi({ address, next }),
101
+ options: {
102
+ headers: {
103
+ Version: "1"
104
+ }
105
+ },
100
106
  timeout: 15e3
101
107
  });
102
108
  if (!nftApiResponse) {
103
109
  return nfts;
104
110
  }
105
- const newNfts = await Promise.all(
106
- nftApiResponse.nfts.map(async (nftV2) => {
107
- const nftV1 = mapOpenSeaNftV2ToV1(nftV2);
108
- if (!nftV1.image_url && nftV2.metadata_url) {
109
- const nftDetails = await safelyExecute(
110
- () => timeoutFetch(
111
- this.getNftApi({
112
- contractAddress: nftV2.contract,
113
- tokenId: nftV2.identifier
114
- }),
115
- void 0,
116
- 1e3
117
- ).then((r) => r.json())
118
- );
119
- nftV1.image_original_url = nftDetails?.nft?.image_url ?? null;
120
- }
121
- return nftV1;
122
- })
111
+ const newNfts = nftApiResponse.tokens.filter(
112
+ (elm) => elm.token.isSpam === false && (elm.blockaidResult?.result_type ? elm.blockaidResult?.result_type === "Benign" /* Benign */ : true)
123
113
  );
124
114
  nfts = [...nfts, ...newNfts];
125
- } while (next = nftApiResponse.next);
115
+ } while (next = nftApiResponse.continuation);
126
116
  return nfts;
127
117
  }
128
118
  async _executePoll(networkClientId, options) {
@@ -182,50 +172,45 @@ var NftDetectionController = class extends StaticIntervalPollingControllerV1 {
182
172
  const apiNfts = await this.getOwnerNfts(userAddress);
183
173
  const addNftPromises = apiNfts.map(async (nft) => {
184
174
  const {
185
- token_id,
186
- num_sales,
187
- background_color,
188
- image_url,
189
- image_preview_url,
190
- image_thumbnail_url,
191
- image_original_url,
192
- animation_url,
193
- animation_original_url,
175
+ tokenId: token_id,
176
+ contract,
177
+ kind,
178
+ image: image_url,
179
+ imageSmall: image_thumbnail_url,
180
+ metadata: { imageOriginal: image_original_url } = {},
194
181
  name,
195
182
  description,
196
- external_link,
197
- creator,
198
- asset_contract: { address, schema_name },
199
- last_sale
200
- } = nft;
183
+ attributes,
184
+ topBid,
185
+ lastSale,
186
+ rarityRank,
187
+ rarityScore,
188
+ collection
189
+ } = nft.token;
201
190
  let ignored;
202
191
  const { ignoredNfts } = this.getNftState();
203
192
  if (ignoredNfts.length) {
204
193
  ignored = ignoredNfts.find((c) => {
205
- return c.address === toChecksumHexAddress(address) && c.tokenId === token_id;
194
+ return c.address === toChecksumHexAddress(contract) && c.tokenId === token_id;
206
195
  });
207
196
  }
208
197
  if (!ignored) {
209
198
  const nftMetadata = Object.assign(
210
199
  {},
211
200
  { name },
212
- creator && { creator },
213
201
  description && { description },
214
202
  image_url && { image: image_url },
215
- num_sales && { numberOfSales: num_sales },
216
- background_color && { backgroundColor: background_color },
217
- image_preview_url && { imagePreview: image_preview_url },
218
203
  image_thumbnail_url && { imageThumbnail: image_thumbnail_url },
219
204
  image_original_url && { imageOriginal: image_original_url },
220
- animation_url && { animation: animation_url },
221
- animation_original_url && {
222
- animationOriginal: animation_original_url
223
- },
224
- schema_name && { standard: schema_name },
225
- external_link && { externalLink: external_link },
226
- last_sale && { lastSale: last_sale }
205
+ kind && { standard: kind.toUpperCase() },
206
+ lastSale && { lastSale },
207
+ attributes && { attributes },
208
+ topBid && { topBid },
209
+ rarityRank && { rarityRank },
210
+ rarityScore && { rarityScore },
211
+ collection && { collection }
227
212
  );
228
- await this.addNft(address, token_id, {
213
+ await this.addNft(contract, token_id, {
229
214
  nftMetadata,
230
215
  userAddress,
231
216
  source: "detected" /* Detected */,
@@ -239,7 +224,8 @@ var NftDetectionController = class extends StaticIntervalPollingControllerV1 {
239
224
  var NftDetectionController_default = NftDetectionController;
240
225
 
241
226
  export {
227
+ BlockaidResultType,
242
228
  NftDetectionController,
243
229
  NftDetectionController_default
244
230
  };
245
- //# sourceMappingURL=chunk-GLZ66IRX.mjs.map
231
+ //# sourceMappingURL=chunk-KDMDWUVX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/NftDetectionController.ts"],"sourcesContent":["import type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport {\n fetchWithErrorHandling,\n toChecksumHexAddress,\n ChainId,\n NFT_API_BASE_URL,\n} from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkController,\n NetworkState,\n NetworkClient,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { Source } from './constants';\nimport {\n type NftController,\n type NftState,\n type NftMetadata,\n} from './NftController';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * @type ApiNft\n *\n * NFT object coming from OpenSea api\n * @property token_id - The NFT identifier\n * @property num_sales - Number of sales\n * @property background_color - The background color to be displayed with the item\n * @property image_url - URI of an image associated with this NFT\n * @property image_preview_url - URI of a smaller image associated with this NFT\n * @property image_thumbnail_url - URI of a thumbnail image associated with this NFT\n * @property image_original_url - URI of the original image associated with this NFT\n * @property animation_url - URI of a animation associated with this NFT\n * @property animation_original_url - URI of the original animation associated with this NFT\n * @property name - The NFT name\n * @property description - The NFT description\n * @property external_link - External link containing additional information\n * @property assetContract - The NFT contract information object\n * @property creator - The NFT owner information object\n * @property lastSale - When this item was last sold\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNft {\n token_id: string;\n num_sales: number | null;\n background_color: string | null;\n image_url: string | null;\n image_preview_url: string | null;\n image_thumbnail_url: string | null;\n image_original_url: string | null;\n animation_url: string | null;\n animation_original_url: string | null;\n name: string | null;\n description: string | null;\n external_link: string | null;\n asset_contract: ApiNftContract;\n creator: ApiNftCreator;\n last_sale: ApiNftLastSale | null;\n}\n\n/**\n * @type ApiNftContract\n *\n * NFT contract object coming from OpenSea api\n * @property address - Address of the NFT contract\n * @property asset_contract_type - The NFT type, it could be `semi-fungible` or `non-fungible`\n * @property created_date - Creation date\n * @property collection - Object containing the contract name and URI of an image associated\n * @property schema_name - The schema followed by the contract, it could be `ERC721` or `ERC1155`\n * @property symbol - The NFT contract symbol\n * @property total_supply - Total supply of NFTs\n * @property description - The NFT contract description\n * @property external_link - External link containing additional information\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNftContract {\n address: string;\n asset_contract_type: string | null;\n created_date: string | null;\n schema_name: string | null;\n symbol: string | null;\n total_supply: string | null;\n description: string | null;\n external_link: string | null;\n collection: {\n name: string | null;\n image_url?: string | null;\n tokenCount?: string | null;\n };\n}\n\n/**\n * @type ApiNftLastSale\n *\n * NFT sale object coming from OpenSea api\n * @property event_timestamp - Object containing a `username`\n * @property total_price - URI of NFT image associated with this owner\n * @property transaction - Object containing transaction_hash and block_hash\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNftLastSale {\n event_timestamp: string;\n total_price: string;\n transaction: { transaction_hash: string; block_hash: string };\n}\n\n/**\n * @type ApiNftCreator\n *\n * NFT creator object coming from OpenSea api\n * @property user - Object containing a `username`\n * @property profile_img_url - URI of NFT image associated with this owner\n * @property address - The owner address\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ApiNftCreator {\n user: { username: string };\n profile_img_url: string;\n address: string;\n}\n\n/**\n * @type NftDetectionConfig\n *\n * NftDetection configuration\n * @property interval - Polling interval used to fetch new token rates\n * @property chainId - Current chain ID\n * @property selectedAddress - Vault selected address\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface NftDetectionConfig extends BaseConfig {\n interval: number;\n chainId: Hex;\n selectedAddress: string;\n}\n\nexport type ReservoirResponse = {\n tokens: TokensResponse[];\n continuation?: string;\n};\n\nexport type TokensResponse = {\n token: TokenResponse;\n ownership: Ownership;\n market?: Market;\n blockaidResult?: Blockaid;\n};\n\nexport enum BlockaidResultType {\n Benign = 'Benign',\n Spam = 'Spam',\n Warning = 'Warning',\n Malicious = 'Malicious',\n}\n\nexport type Blockaid = {\n contract: string;\n chainId: number;\n result_type: BlockaidResultType;\n malicious_score: string;\n attack_types: object;\n};\n\nexport type Market = {\n floorAsk?: FloorAsk;\n topBid?: TopBid;\n};\n\nexport type TokenResponse = {\n chainId: number;\n contract: string;\n tokenId: string;\n kind?: string;\n name?: string;\n image?: string;\n imageSmall?: string;\n imageLarge?: string;\n metadata?: Metadata;\n description?: string;\n supply?: number;\n remainingSupply?: number;\n rarityScore?: number;\n rarity?: number;\n rarityRank?: number;\n media?: string;\n isFlagged?: boolean;\n isSpam?: boolean;\n isNsfw?: boolean;\n metadataDisabled?: boolean;\n lastFlagUpdate?: string;\n lastFlagChange?: string;\n collection?: Collection;\n lastSale?: LastSale;\n topBid?: TopBid;\n lastAppraisalValue?: number;\n attributes?: Attributes[];\n};\n\nexport type TopBid = {\n id?: string;\n price?: Price;\n source?: {\n id?: string;\n domain?: string;\n name?: string;\n icon?: string;\n url?: string;\n };\n};\n\nexport type LastSale = {\n saleId?: string;\n token?: {\n contract?: string;\n tokenId?: string;\n name?: string;\n image?: string;\n collection?: {\n id?: string;\n name?: string;\n };\n };\n orderSource?: string;\n orderSide?: 'ask' | 'bid';\n orderKind?: string;\n orderId?: string;\n from?: string;\n to?: string;\n amount?: string;\n fillSource?: string;\n block?: number;\n txHash?: string;\n logIndex?: number;\n batchIndex?: number;\n timestamp?: number;\n price?: Price;\n washTradingScore?: number;\n royaltyFeeBps?: number;\n marketplaceFeeBps?: number;\n paidFullRoyalty?: boolean;\n feeBreakdown?: FeeBreakdown[];\n isDeleted?: boolean;\n createdAt?: string;\n updatedAt?: string;\n};\n\nexport type FeeBreakdown = {\n kind?: string;\n bps?: number;\n recipient?: string;\n source?: string;\n rawAmount?: string;\n};\n\nexport type Attributes = {\n key?: string;\n kind?: string;\n value: string;\n tokenCount?: number;\n onSaleCount?: number;\n floorAskPrice?: Price | null;\n topBidValue?: number | null;\n createdAt?: string;\n};\n\nexport type Collection = {\n id?: string;\n name?: string;\n slug?: string;\n symbol?: string;\n imageUrl?: string;\n image?: string;\n isSpam?: boolean;\n isNsfw?: boolean;\n creator?: string;\n tokenCount?: string;\n metadataDisabled?: boolean;\n openseaVerificationStatus?: string;\n floorAskPrice?: Price;\n royaltiesBps?: number;\n royalties?: Royalties[];\n};\n\nexport type Royalties = {\n bps?: number;\n recipient?: string;\n};\n\nexport type Ownership = {\n tokenCount?: string;\n onSaleCount?: string;\n floorAsk?: FloorAsk;\n acquiredAt?: string;\n};\n\nexport type FloorAsk = {\n id?: string;\n price?: Price;\n maker?: string;\n kind?: string;\n validFrom?: number;\n validUntil?: number;\n source?: Source;\n rawData?: Metadata;\n isNativeOffChainCancellable?: boolean;\n};\n\nexport type Price = {\n currency?: {\n contract?: string;\n name?: string;\n symbol?: string;\n decimals?: number;\n chainId?: number;\n };\n amount?: {\n raw?: string;\n decimal?: number;\n usd?: number;\n native?: number;\n };\n netAmount?: {\n raw?: string;\n decimal?: number;\n usd?: number;\n native?: number;\n };\n};\n\nexport type Metadata = {\n imageOriginal?: string;\n tokenURI?: string;\n};\n\n/**\n * Controller that passively polls on a set interval for NFT auto detection\n */\nexport class NftDetectionController extends StaticIntervalPollingControllerV1<\n NftDetectionConfig,\n BaseState\n> {\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private getOwnerNftApi({\n address,\n next,\n }: {\n address: string;\n next?: string;\n }) {\n return `${NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=200&includeTopBid=true&continuation=${\n next ?? ''\n }`;\n }\n\n private async getOwnerNfts(address: string) {\n let nftApiResponse: ReservoirResponse;\n let nfts: TokensResponse[] = [];\n let next;\n\n do {\n nftApiResponse = await fetchWithErrorHandling({\n url: this.getOwnerNftApi({ address, next }),\n options: {\n headers: {\n Version: '1',\n },\n },\n timeout: 15000,\n });\n\n if (!nftApiResponse) {\n return nfts;\n }\n\n const newNfts = nftApiResponse.tokens.filter(\n (elm) =>\n elm.token.isSpam === false &&\n (elm.blockaidResult?.result_type\n ? elm.blockaidResult?.result_type === BlockaidResultType.Benign\n : true),\n );\n\n nfts = [...nfts, ...newNfts];\n } while ((next = nftApiResponse.continuation));\n\n return nfts;\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'NftDetectionController';\n\n private readonly getOpenSeaApiKey: () => string | undefined;\n\n private readonly addNft: NftController['addNft'];\n\n private readonly getNftApi: NftController['getNftApi'];\n\n private readonly getNftState: () => NftState;\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n /**\n * Creates an NftDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNftsStateChange - Allows subscribing to assets controller state changes.\n * @param options.onPreferencesStateChange - Allows subscribing to preferences controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param options.getOpenSeaApiKey - Gets the OpenSea API key, if one is set.\n * @param options.addNft - Add an NFT.\n * @param options.getNftApi - Gets the URL to fetch an NFT from OpenSea.\n * @param options.getNftState - Gets the current state of the Assets controller.\n * @param options.getNetworkClientById - Gets the network client by ID, from the NetworkController.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n chainId: initialChainId,\n getNetworkClientById,\n onPreferencesStateChange,\n onNetworkStateChange,\n getOpenSeaApiKey,\n addNft,\n getNftApi,\n getNftState,\n }: {\n chainId: Hex;\n getNetworkClientById: NetworkController['getNetworkClientById'];\n onNftsStateChange: (listener: (nftsState: NftState) => void) => void;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getOpenSeaApiKey: () => string | undefined;\n addNft: NftController['addNft'];\n getNftApi: NftController['getNftApi'];\n getNftState: () => NftState;\n },\n config?: Partial<NftDetectionConfig>,\n state?: Partial<BaseState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: DEFAULT_INTERVAL,\n chainId: initialChainId,\n selectedAddress: '',\n disabled: true,\n };\n this.initialize();\n this.getNftState = getNftState;\n this.getNetworkClientById = getNetworkClientById;\n onPreferencesStateChange(({ selectedAddress, useNftDetection }) => {\n const { selectedAddress: previouslySelectedAddress, disabled } =\n this.config;\n\n if (\n selectedAddress !== previouslySelectedAddress ||\n !useNftDetection !== disabled\n ) {\n this.configure({ selectedAddress, disabled: !useNftDetection });\n if (useNftDetection) {\n this.start();\n } else {\n this.stop();\n }\n }\n });\n\n onNetworkStateChange(({ providerConfig }) => {\n this.configure({\n chainId: providerConfig.chainId,\n });\n });\n this.getOpenSeaApiKey = getOpenSeaApiKey;\n this.addNft = addNft;\n this.getNftApi = getNftApi;\n this.setIntervalLength(this.config.interval);\n }\n\n async _executePoll(\n networkClientId: string,\n options: { address: string },\n ): Promise<void> {\n await this.detectNfts({ networkClientId, userAddress: options.address });\n }\n\n /**\n * Start polling for the currency rate.\n */\n async start() {\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n\n await this.startPolling();\n }\n\n /**\n * Stop polling for the currency rate.\n */\n stop() {\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - An interval on which to poll.\n */\n private async startPolling(interval?: number): Promise<void> {\n interval && this.configure({ interval }, false, false);\n this.stopPolling();\n await this.detectNfts();\n this.intervalId = setInterval(async () => {\n await this.detectNfts();\n }, this.config.interval);\n }\n\n /**\n * Checks whether network is mainnet or not.\n *\n * @returns Whether current network is mainnet.\n */\n isMainnet = (): boolean => this.config.chainId === ChainId.mainnet;\n\n isMainnetByNetworkClientId = (networkClient: NetworkClient): boolean => {\n return networkClient.configuration.chainId === ChainId.mainnet;\n };\n\n /**\n * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are\n * added.\n *\n * @param options - Options bag.\n * @param options.networkClientId - The network client ID to detect NFTs on.\n * @param options.userAddress - The address to detect NFTs for.\n */\n async detectNfts(\n {\n networkClientId,\n userAddress,\n }: {\n networkClientId?: NetworkClientId;\n userAddress: string;\n } = { userAddress: this.config.selectedAddress },\n ) {\n /* istanbul ignore if */\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n /* istanbul ignore else */\n if (!userAddress) {\n return;\n }\n\n const apiNfts = await this.getOwnerNfts(userAddress);\n const addNftPromises = apiNfts.map(async (nft) => {\n const {\n tokenId: token_id,\n contract,\n kind,\n image: image_url,\n imageSmall: image_thumbnail_url,\n metadata: { imageOriginal: image_original_url } = {},\n name,\n description,\n attributes,\n topBid,\n lastSale,\n rarityRank,\n rarityScore,\n collection,\n } = nft.token;\n\n let ignored;\n /* istanbul ignore else */\n const { ignoredNfts } = this.getNftState();\n if (ignoredNfts.length) {\n ignored = ignoredNfts.find((c) => {\n /* istanbul ignore next */\n return (\n c.address === toChecksumHexAddress(contract) &&\n c.tokenId === token_id\n );\n });\n }\n\n /* istanbul ignore else */\n if (!ignored) {\n /* istanbul ignore next */\n const nftMetadata: NftMetadata = Object.assign(\n {},\n { name },\n description && { description },\n image_url && { image: image_url },\n image_thumbnail_url && { imageThumbnail: image_thumbnail_url },\n image_original_url && { imageOriginal: image_original_url },\n kind && { standard: kind.toUpperCase() },\n lastSale && { lastSale },\n attributes && { attributes },\n topBid && { topBid },\n rarityRank && { rarityRank },\n rarityScore && { rarityScore },\n collection && { collection },\n );\n\n await this.addNft(contract, token_id, {\n nftMetadata,\n userAddress,\n source: Source.Detected,\n networkClientId,\n });\n }\n });\n await Promise.all(addNftPromises);\n }\n}\n\nexport default NftDetectionController;\n"],"mappings":"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","names":["BlockaidResultType"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ethersBigNumberToBN
3
- } from "./chunk-E5PIGGYR.mjs";
3
+ } from "./chunk-ZPAX2HLQ.mjs";
4
4
 
5
5
  // src/Standards/ERC20Standard.ts
6
6
  import { toUtf8 } from "@ethereumjs/util";
@@ -112,4 +112,4 @@ var ERC20Standard = class {
112
112
  export {
113
113
  ERC20Standard
114
114
  };
115
- //# sourceMappingURL=chunk-MQ7TIWBK.mjs.map
115
+ //# sourceMappingURL=chunk-KS4MOA2T.mjs.map
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
2
 
3
- var _chunkRELRWIJNjs = require('./chunk-RELRWIJN.js');
3
+ var _chunkD6BDJYSKjs = require('./chunk-D6BDJYSK.js');
4
4
 
5
5
 
6
6
 
@@ -99,7 +99,7 @@ var TokenDetectionController = class extends _pollingcontroller.StaticIntervalPo
99
99
  _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _networkClientId, networkClientId);
100
100
  const { useTokenDetection: defaultUseTokenDetection } = this.messagingSystem.call("PreferencesController:getState");
101
101
  _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledFromPreferences, defaultUseTokenDetection);
102
- _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledForNetwork, _chunkRELRWIJNjs.isTokenDetectionSupportedForNetwork.call(void 0, chainId));
102
+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledForNetwork, _chunkD6BDJYSKjs.isTokenDetectionSupportedForNetwork.call(void 0, chainId));
103
103
  _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getBalancesInSingleCall, getBalancesInSingleCall);
104
104
  _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _trackMetaMetricsEvent, trackMetaMetricsEvent);
105
105
  const { isUnlocked } = this.messagingSystem.call(
@@ -169,7 +169,7 @@ var TokenDetectionController = class extends _pollingcontroller.StaticIntervalPo
169
169
  const { chainId, networkClientId: selectedNetworkClientId } = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getCorrectChainIdAndNetworkClientId, getCorrectChainIdAndNetworkClientId_fn).call(this, networkClientId);
170
170
  const chainIdAgainstWhichToDetect = chainId;
171
171
  const networkClientIdAgainstWhichToDetect = selectedNetworkClientId;
172
- if (!_chunkRELRWIJNjs.isTokenDetectionSupportedForNetwork.call(void 0, chainIdAgainstWhichToDetect)) {
172
+ if (!_chunkD6BDJYSKjs.isTokenDetectionSupportedForNetwork.call(void 0, chainIdAgainstWhichToDetect)) {
173
173
  return;
174
174
  }
175
175
  if (!_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _isDetectionEnabledFromPreferences) && chainIdAgainstWhichToDetect !== _controllerutils.ChainId.mainnet) {
@@ -253,7 +253,7 @@ registerEventListeners_fn = function() {
253
253
  async ({ selectedNetworkClientId }) => {
254
254
  const isNetworkClientIdChanged = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _networkClientId) !== selectedNetworkClientId;
255
255
  const { chainId: newChainId } = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getCorrectChainIdAndNetworkClientId, getCorrectChainIdAndNetworkClientId_fn).call(this, selectedNetworkClientId);
256
- _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledForNetwork, _chunkRELRWIJNjs.isTokenDetectionSupportedForNetwork.call(void 0, newChainId));
256
+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledForNetwork, _chunkD6BDJYSKjs.isTokenDetectionSupportedForNetwork.call(void 0, newChainId));
257
257
  if (isNetworkClientIdChanged && _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _isDetectionEnabledForNetwork)) {
258
258
  _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _networkClientId, selectedNetworkClientId);
259
259
  await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _restartTokenDetection, restartTokenDetection_fn).call(this, {
@@ -408,4 +408,4 @@ var TokenDetectionController_default = TokenDetectionController;
408
408
 
409
409
 
410
410
  exports.isEqualCaseInsensitive = isEqualCaseInsensitive; exports.STATIC_MAINNET_TOKEN_LIST = STATIC_MAINNET_TOKEN_LIST; exports.controllerName = controllerName; exports.TokenDetectionController = TokenDetectionController; exports.TokenDetectionController_default = TokenDetectionController_default;
411
- //# sourceMappingURL=chunk-XEZJ5XMV.js.map
411
+ //# sourceMappingURL=chunk-LBPVKXXG.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ethersBigNumberToBN,
3
3
  getFormattedIpfsUrl
4
- } from "./chunk-E5PIGGYR.mjs";
4
+ } from "./chunk-ZPAX2HLQ.mjs";
5
5
 
6
6
  // src/Standards/NftStandards/ERC1155/ERC1155Standard.ts
7
7
  import { Contract } from "@ethersproject/contracts";
@@ -212,4 +212,4 @@ var ERC1155Standard = class {
212
212
  export {
213
213
  ERC1155Standard
214
214
  };
215
- //# sourceMappingURL=chunk-CEENXWOB.mjs.map
215
+ //# sourceMappingURL=chunk-N5H5KDJZ.mjs.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  TOKEN_PRICES_BATCH_SIZE,
6
6
  reduceInBatchesSerially
7
- } from "./chunk-E5PIGGYR.mjs";
7
+ } from "./chunk-ZPAX2HLQ.mjs";
8
8
  import {
9
9
  __privateAdd,
10
10
  __privateGet,
@@ -415,4 +415,4 @@ export {
415
415
  TokenRatesController,
416
416
  TokenRatesController_default
417
417
  };
418
- //# sourceMappingURL=chunk-25YSNHCK.mjs.map
418
+ //# sourceMappingURL=chunk-NHX4QGOD.mjs.map