@metamask-previews/assets-controllers 93.1.0-preview-f557eade → 93.1.0-preview-aabe1c65
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.
- package/CHANGELOG.md +1 -0
- package/dist/NftController.cjs +68 -19
- package/dist/NftController.cjs.map +1 -1
- package/dist/NftController.d.cts +19 -27
- package/dist/NftController.d.cts.map +1 -1
- package/dist/NftController.d.mts +19 -27
- package/dist/NftController.d.mts.map +1 -1
- package/dist/NftController.mjs +69 -20
- package/dist/NftController.mjs.map +1 -1
- package/dist/NftDetectionController.cjs +16 -14
- package/dist/NftDetectionController.cjs.map +1 -1
- package/dist/NftDetectionController.d.cts +3 -3
- package/dist/NftDetectionController.d.cts.map +1 -1
- package/dist/NftDetectionController.d.mts +3 -3
- package/dist/NftDetectionController.d.mts.map +1 -1
- package/dist/NftDetectionController.mjs +17 -15
- package/dist/NftDetectionController.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
17
|
|
|
18
18
|
### Fixed
|
|
19
19
|
|
|
20
|
+
- **BREAKING:** `NftDetectionController` now calls a new function `NftController:addNfts` that reduces API calls to bulk-scan to batch multiple NFTs URLs ([#7411](https://github.com/MetaMask/core/pull/7411))
|
|
20
21
|
- Added decimal precision (default 9dp) for `CurrencyRateController` `conversionRate` and `conversionRate` properties. ([#7324](https://github.com/MetaMask/core/pull/7324))
|
|
21
22
|
- This fixes any BigNumber conversion errors due to exceeding the 15 significant digit limit
|
|
22
23
|
|
package/dist/NftController.cjs
CHANGED
|
@@ -253,6 +253,42 @@ class NftController extends base_controller_1.BaseController {
|
|
|
253
253
|
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addIndividualNft).call(this, checksumHexAddress, tokenId, nftMetadata, nftContract, chainId, addressToSearch, source);
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Adds multiple NFTs and respective NFT contracts to the stored NFT and NFT contracts lists.
|
|
258
|
+
*
|
|
259
|
+
* @param nfts - An array of NFT objects to add.
|
|
260
|
+
* @param nfts[].tokenAddress - Hex address of the NFT contract.
|
|
261
|
+
* @param nfts[].tokenId - The NFT identifier.
|
|
262
|
+
* @param nfts[].nftMetadata - NFT metadata including chainId.
|
|
263
|
+
* @param userAddress - The address of the current user.
|
|
264
|
+
* @param source - Whether the NFT was detected, added manually or suggested by a dapp. Defaults to Source.Custom.
|
|
265
|
+
* @returns Promise resolving to the current NFT list.
|
|
266
|
+
*/
|
|
267
|
+
async addNfts(nfts, userAddress, source = constants_1.Source.Custom) {
|
|
268
|
+
const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
|
|
269
|
+
if (!addressToSearch) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// Remember max number of urls this allows is 250
|
|
273
|
+
const sanitizedNftMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_bulkSanitizeNftMetadata).call(this, nfts.map((nft) => nft.nftMetadata));
|
|
274
|
+
for (const [index, nft] of nfts.entries()) {
|
|
275
|
+
const checksumHexAddress = (0, controller_utils_1.toChecksumHexAddress)(nft.tokenAddress);
|
|
276
|
+
const hexChainId = (0, controller_utils_1.toHex)(nft.nftMetadata.chainId);
|
|
277
|
+
const networkClientId = this.messenger.call('NetworkController:findNetworkClientIdByChainId', hexChainId);
|
|
278
|
+
const newNftContracts = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addNftContract).call(this, networkClientId, {
|
|
279
|
+
tokenAddress: checksumHexAddress,
|
|
280
|
+
userAddress: addressToSearch,
|
|
281
|
+
source,
|
|
282
|
+
nftMetadata: sanitizedNftMetadata[index],
|
|
283
|
+
});
|
|
284
|
+
// If NFT contract was not added, do not add individual NFT
|
|
285
|
+
const nftContract = newNftContracts.find((contract) => contract.address.toLowerCase() === checksumHexAddress.toLowerCase());
|
|
286
|
+
// If NFT contract information, add individual NFT
|
|
287
|
+
if (nftContract) {
|
|
288
|
+
await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addIndividualNft).call(this, checksumHexAddress, nft.tokenId, sanitizedNftMetadata[index], nftContract, hexChainId, addressToSearch, source);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
256
292
|
/**
|
|
257
293
|
* Refetches NFT metadata and updates the state
|
|
258
294
|
*
|
|
@@ -1216,27 +1252,40 @@ async function _NftController_bulkSanitizeNftMetadata(metadataList) {
|
|
|
1216
1252
|
return sanitizedMetadataList;
|
|
1217
1253
|
}
|
|
1218
1254
|
try {
|
|
1219
|
-
//
|
|
1220
|
-
const
|
|
1221
|
-
//
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
else {
|
|
1236
|
-
delete sanitizedMetadataList[metadataIndex][fieldName];
|
|
1255
|
+
// PhishingController has a 250 URL limit, so batch if needed
|
|
1256
|
+
const MAX_URLS_PER_BATCH = 250;
|
|
1257
|
+
// Process URLs in batches serially
|
|
1258
|
+
const blockedUrls = await (0, assetsUtil_1.reduceInBatchesSerially)({
|
|
1259
|
+
values: urlsToCheck,
|
|
1260
|
+
batchSize: MAX_URLS_PER_BATCH,
|
|
1261
|
+
eachBatch: async (workingBlockedUrls, batch) => {
|
|
1262
|
+
// Use bulkScanUrls to check this batch
|
|
1263
|
+
const bulkScanResponse = await this.messenger.call('PhishingController:bulkScanUrls', batch);
|
|
1264
|
+
// Collect blocked URLs from this batch
|
|
1265
|
+
Object.entries(bulkScanResponse.results).forEach(([url, result]) => {
|
|
1266
|
+
if (result.recommendedAction === phishing_controller_1.RecommendedAction.Block) {
|
|
1267
|
+
// Type assertion is safe here as we always initialize with a Set and return a Set
|
|
1268
|
+
workingBlockedUrls.add(url);
|
|
1237
1269
|
}
|
|
1238
1270
|
});
|
|
1239
|
-
|
|
1271
|
+
return workingBlockedUrls;
|
|
1272
|
+
},
|
|
1273
|
+
initialResult: new Set(),
|
|
1274
|
+
});
|
|
1275
|
+
// Apply scan results to all metadata objects
|
|
1276
|
+
blockedUrls.forEach((url) => {
|
|
1277
|
+
urlMap[url].forEach(({ metadataIndex, fieldName }) => {
|
|
1278
|
+
if (fieldName === 'collection.externalLink' &&
|
|
1279
|
+
sanitizedMetadataList[metadataIndex].collection) {
|
|
1280
|
+
const { collection } = sanitizedMetadataList[metadataIndex];
|
|
1281
|
+
if (collection && 'externalLink' in collection) {
|
|
1282
|
+
delete collection.externalLink;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
else {
|
|
1286
|
+
delete sanitizedMetadataList[metadataIndex][fieldName];
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1240
1289
|
});
|
|
1241
1290
|
}
|
|
1242
1291
|
catch (error) {
|