@metamask-previews/assets-controllers 66.0.0-preview-e9f8bc88 → 68.0.0-preview-510657d5

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.
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _NftController_instances, _NftController_mutex, _NftController_selectedAccountId, _NftController_chainId, _NftController_ipfsGateway, _NftController_openSeaEnabled, _NftController_useIpfsSubdomains, _NftController_isIpfsGatewayEnabled, _NftController_onNftAdded, _NftController_onNetworkControllerNetworkDidChange, _NftController_onPreferencesControllerStateChange, _NftController_onSelectedAccountChange, _NftController_updateNestedNftState, _NftController_getNftCollectionApi, _NftController_getNftInformationFromApi, _NftController_getNftInformationFromTokenURI, _NftController_getNftURIAndStandard, _NftController_getNftInformation, _NftController_getNftContractInformationFromContract, _NftController_getNftContractInformation, _NftController_addIndividualNft, _NftController_addNftContract, _NftController_removeAndIgnoreIndividualNft, _NftController_removeIndividualNft, _NftController_removeNftContract, _NftController_validateWatchNft, _NftController_getCorrectChainId, _NftController_getAddressOrSelectedAddress, _NftController_updateNftUpdateForAccount, _NftController_bulkSanitizeNftMetadata, _NftController_sanitizeNftMetadata;
12
+ var _NftController_instances, _NftController_mutex, _NftController_selectedAccountId, _NftController_ipfsGateway, _NftController_openSeaEnabled, _NftController_useIpfsSubdomains, _NftController_isIpfsGatewayEnabled, _NftController_onNftAdded, _NftController_onPreferencesControllerStateChange, _NftController_onSelectedAccountChange, _NftController_updateNestedNftState, _NftController_getNftCollectionApi, _NftController_getNftInformationFromApi, _NftController_getNftInformationFromTokenURI, _NftController_getNftURIAndStandard, _NftController_getNftInformation, _NftController_getNftContractInformationFromContract, _NftController_getNftContractInformation, _NftController_addIndividualNft, _NftController_addNftContract, _NftController_removeAndIgnoreIndividualNft, _NftController_removeIndividualNft, _NftController_removeNftContract, _NftController_validateWatchNft, _NftController_getAddressOrSelectedAddress, _NftController_updateNftUpdateForAccount, _NftController_bulkSanitizeNftMetadata, _NftController_sanitizeNftMetadata;
13
13
  function $importDefault(module) {
14
14
  if (module?.__esModule) {
15
15
  return module.default;
@@ -18,7 +18,7 @@ function $importDefault(module) {
18
18
  }
19
19
  import { isAddress } from "@ethersproject/address";
20
20
  import { BaseController } from "@metamask/base-controller";
21
- import { safelyExecute, handleFetch, toChecksumHexAddress, BNToHex, fetchWithErrorHandling, IPFS_DEFAULT_GATEWAY_URL, ERC721, ERC1155, ApprovalType, NFT_API_BASE_URL, NFT_API_VERSION, convertHexToDecimal } from "@metamask/controller-utils";
21
+ import { safelyExecute, handleFetch, toChecksumHexAddress, BNToHex, fetchWithErrorHandling, IPFS_DEFAULT_GATEWAY_URL, ERC721, ERC1155, ApprovalType, NFT_API_BASE_URL, NFT_API_VERSION, convertHexToDecimal, toHex } from "@metamask/controller-utils";
22
22
  import { RecommendedAction } from "@metamask/phishing-controller";
23
23
  import { rpcErrors } from "@metamask/rpc-errors";
24
24
  import { remove0x } from "@metamask/utils";
@@ -53,7 +53,6 @@ export class NftController extends BaseController {
53
53
  * Creates an NftController instance.
54
54
  *
55
55
  * @param options - The controller options.
56
- * @param options.chainId - The chain ID of the current network.
57
56
  * @param options.ipfsGateway - The configured IPFS gateway.
58
57
  * @param options.openSeaEnabled - Controls whether the OpenSea API is used.
59
58
  * @param options.useIpfsSubdomains - Controls whether IPFS subdomains are used.
@@ -63,7 +62,7 @@ export class NftController extends BaseController {
63
62
  * @param options.messenger - The messenger.
64
63
  * @param options.state - Initial state to set on this controller.
65
64
  */
66
- constructor({ chainId: initialChainId, ipfsGateway = IPFS_DEFAULT_GATEWAY_URL, openSeaEnabled = false, useIpfsSubdomains = true, isIpfsGatewayEnabled = true, onNftAdded, messenger, state = {}, }) {
65
+ constructor({ ipfsGateway = IPFS_DEFAULT_GATEWAY_URL, openSeaEnabled = false, useIpfsSubdomains = true, isIpfsGatewayEnabled = true, onNftAdded, messenger, state = {}, }) {
67
66
  super({
68
67
  name: controllerName,
69
68
  metadata: nftControllerMetadata,
@@ -76,14 +75,12 @@ export class NftController extends BaseController {
76
75
  _NftController_instances.add(this);
77
76
  _NftController_mutex.set(this, new Mutex());
78
77
  _NftController_selectedAccountId.set(this, void 0);
79
- _NftController_chainId.set(this, void 0);
80
78
  _NftController_ipfsGateway.set(this, void 0);
81
79
  _NftController_openSeaEnabled.set(this, void 0);
82
80
  _NftController_useIpfsSubdomains.set(this, void 0);
83
81
  _NftController_isIpfsGatewayEnabled.set(this, void 0);
84
82
  _NftController_onNftAdded.set(this, void 0);
85
83
  __classPrivateFieldSet(this, _NftController_selectedAccountId, this.messagingSystem.call('AccountsController:getSelectedAccount').id, "f");
86
- __classPrivateFieldSet(this, _NftController_chainId, initialChainId, "f");
87
84
  __classPrivateFieldSet(this, _NftController_ipfsGateway, ipfsGateway, "f");
88
85
  __classPrivateFieldSet(this, _NftController_openSeaEnabled, openSeaEnabled, "f");
89
86
  __classPrivateFieldSet(this, _NftController_useIpfsSubdomains, useIpfsSubdomains, "f");
@@ -93,7 +90,6 @@ export class NftController extends BaseController {
93
90
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
94
91
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
95
92
  __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_onPreferencesControllerStateChange).bind(this));
96
- this.messagingSystem.subscribe('NetworkController:networkDidChange', __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_onNetworkControllerNetworkDidChange).bind(this));
97
93
  this.messagingSystem.subscribe('AccountsController:selectedEvmAccountChange',
98
94
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
99
95
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
@@ -113,17 +109,20 @@ export class NftController extends BaseController {
113
109
  * @param asset.tokenId - The ID of the asset.
114
110
  * @param type - The asset type.
115
111
  * @param origin - Domain origin to register the asset from.
112
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
116
113
  * @param options - Options bag.
117
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
118
114
  * @param options.userAddress - The address of the account where the NFT is being added.
119
115
  * @returns Object containing a Promise resolving to the suggestedAsset address if accepted.
120
116
  */
121
- async watchNft(asset, type, origin, { networkClientId, userAddress, } = {}) {
117
+ async watchNft(asset, type, origin, networkClientId, { userAddress, } = {}) {
122
118
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
123
119
  if (!addressToSearch) {
124
120
  return;
125
121
  }
126
- await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_validateWatchNft).call(this, asset, type, addressToSearch);
122
+ if (!networkClientId) {
123
+ throw rpcErrors.invalidParams('Network client id is required');
124
+ }
125
+ await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_validateWatchNft).call(this, asset, type, addressToSearch, networkClientId);
127
126
  const nftMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, asset.address, asset.tokenId, networkClientId);
128
127
  // Sanitize metadata
129
128
  const sanitizedMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_sanitizeNftMetadata).call(this, nftMetadata);
@@ -141,7 +140,7 @@ export class NftController extends BaseController {
141
140
  await this._requestApproval(suggestedNftMeta);
142
141
  const { address, tokenId } = asset;
143
142
  const { name, standard, description, image } = sanitizedMetadata;
144
- await this.addNft(address, tokenId, {
143
+ await this.addNft(address, tokenId, networkClientId, {
145
144
  nftMetadata: {
146
145
  name: name ?? null,
147
146
  description: description ?? null,
@@ -150,7 +149,6 @@ export class NftController extends BaseController {
150
149
  },
151
150
  userAddress,
152
151
  source: Source.Dapp,
153
- networkClientId,
154
152
  });
155
153
  }
156
154
  /**
@@ -167,11 +165,10 @@ export class NftController extends BaseController {
167
165
  * @param ownerAddress - User public address.
168
166
  * @param nftAddress - NFT contract address.
169
167
  * @param tokenId - NFT token ID.
170
- * @param options - Options bag.
171
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
168
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
172
169
  * @returns Promise resolving the NFT ownership.
173
170
  */
174
- async isNftOwner(ownerAddress, nftAddress, tokenId, { networkClientId, } = {}) {
171
+ async isNftOwner(ownerAddress, nftAddress, tokenId, networkClientId) {
175
172
  // Checks the ownership for ERC-721.
176
173
  try {
177
174
  const owner = await this.messagingSystem.call('AssetsContractController:getERC721OwnerOf', nftAddress, tokenId, networkClientId);
@@ -198,20 +195,17 @@ export class NftController extends BaseController {
198
195
  *
199
196
  * @param address - Hex address of the NFT contract.
200
197
  * @param tokenId - The NFT identifier.
198
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
201
199
  * @param options - an object of arguments
202
200
  * @param options.userAddress - The address of the current user.
203
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
204
201
  * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
205
202
  */
206
- async addNftVerifyOwnership(address, tokenId, { userAddress, networkClientId, source, } = {}) {
203
+ async addNftVerifyOwnership(address, tokenId, networkClientId, { userAddress, source, } = {}) {
207
204
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
208
- if (!(await this.isNftOwner(addressToSearch, address, tokenId, {
209
- networkClientId,
210
- }))) {
205
+ if (!(await this.isNftOwner(addressToSearch, address, tokenId, networkClientId))) {
211
206
  throw new Error('This NFT is not owned by the user');
212
207
  }
213
- await this.addNft(address, tokenId, {
214
- networkClientId,
208
+ await this.addNft(address, tokenId, networkClientId, {
215
209
  userAddress: addressToSearch,
216
210
  source,
217
211
  });
@@ -221,22 +215,19 @@ export class NftController extends BaseController {
221
215
  *
222
216
  * @param tokenAddress - Hex address of the NFT contract.
223
217
  * @param tokenId - The NFT identifier.
218
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
224
219
  * @param options - an object of arguments
225
220
  * @param options.nftMetadata - NFT optional metadata.
226
221
  * @param options.userAddress - The address of the current user.
227
222
  * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
228
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
229
- * @param options.chainId - The chain ID to add the NFT to.
230
223
  * @returns Promise resolving to the current NFT list.
231
224
  */
232
- async addNft(tokenAddress, tokenId, { nftMetadata, userAddress, source = Source.Custom, networkClientId, chainId, } = {}) {
225
+ async addNft(tokenAddress, tokenId, networkClientId, { nftMetadata, userAddress, source = Source.Custom, } = {}) {
233
226
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
234
227
  if (!addressToSearch) {
235
228
  return;
236
229
  }
237
230
  const checksumHexAddress = toChecksumHexAddress(tokenAddress);
238
- // TODO: revisit this with Solana support and instead of passing chainId, make sure chainId is read from nftMetadata
239
- const chainIdToAddTo = chainId || __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
240
231
  if (!nftMetadata) {
241
232
  const fetchedMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, checksumHexAddress, tokenId, networkClientId);
242
233
  // Sanitize metadata
@@ -246,23 +237,23 @@ export class NftController extends BaseController {
246
237
  // Sanitize provided metadata
247
238
  nftMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_sanitizeNftMetadata).call(this, nftMetadata);
248
239
  }
249
- const newNftContracts = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addNftContract).call(this, {
240
+ const newNftContracts = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addNftContract).call(this, networkClientId, {
250
241
  tokenAddress: checksumHexAddress,
251
242
  userAddress: addressToSearch,
252
- networkClientId,
253
243
  source,
254
244
  nftMetadata,
255
- chainIdHex: source === Source.Detected ? chainIdToAddTo : undefined,
256
245
  });
257
246
  // If NFT contract was not added, do not add individual NFT
258
247
  const nftContract = newNftContracts.find((contract) => contract.address.toLowerCase() === checksumHexAddress.toLowerCase());
248
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
259
249
  // This is the case when the NFT is added manually and not detected automatically
250
+ // TODO: An improvement would be to make the chainId a required field and return it when getting the NFT information
260
251
  if (!nftMetadata.chainId) {
261
- nftMetadata.chainId = convertHexToDecimal(chainIdToAddTo);
252
+ nftMetadata.chainId = convertHexToDecimal(chainId);
262
253
  }
263
254
  // If NFT contract information, add individual NFT
264
255
  if (nftContract) {
265
- await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addIndividualNft).call(this, checksumHexAddress, tokenId, nftMetadata, nftContract, chainIdToAddTo, addressToSearch, source);
256
+ await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_addIndividualNft).call(this, checksumHexAddress, tokenId, nftMetadata, nftContract, chainId, addressToSearch, source);
266
257
  }
267
258
  }
268
259
  /**
@@ -271,13 +262,11 @@ export class NftController extends BaseController {
271
262
  * @param options - Options for refetching NFT metadata
272
263
  * @param options.nfts - nfts to update metadata for.
273
264
  * @param options.userAddress - The current user address
274
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
275
265
  */
276
- async updateNftMetadata({ nfts, userAddress, networkClientId, }) {
266
+ async updateNftMetadata({ nfts, userAddress, }) {
277
267
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
278
268
  const releaseLock = await __classPrivateFieldGet(this, _NftController_mutex, "f").acquire();
279
269
  try {
280
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
281
270
  const nftsWithChecksumAdr = nfts.map((nft) => {
282
271
  return {
283
272
  ...nft,
@@ -286,7 +275,11 @@ export class NftController extends BaseController {
286
275
  });
287
276
  // Get all unsanitized nft metadata
288
277
  const unsanitizedResults = await Promise.all(nftsWithChecksumAdr.map(async (nft) => {
289
- const resMetadata = await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, nft.address, nft.tokenId, networkClientId);
278
+ // Each NFT should have a chainId; convert nft.chainId to networkClientId
279
+ const networkClientId = this.messagingSystem.call('NetworkController:findNetworkClientIdByChainId', toHex(nft.chainId));
280
+ const resMetadata = networkClientId
281
+ ? await __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformation).call(this, nft.address, nft.tokenId, networkClientId)
282
+ : undefined;
290
283
  return {
291
284
  nft,
292
285
  newMetadata: resMetadata,
@@ -304,19 +297,27 @@ export class NftController extends BaseController {
304
297
  // We want to avoid updating the state if the state and fetched nft info are the same
305
298
  const nftsWithDifferentMetadata = [];
306
299
  const { allNfts } = this.state;
307
- const stateNfts = allNfts[addressToSearch]?.[chainId] || [];
300
+ // get from state allNfts that match nftsWithChecksumAdr
301
+ const stateNfts = nftsWithChecksumAdr.map((nft) => {
302
+ return allNfts[addressToSearch]?.[toHex(nft.chainId)]?.find((nftElement) => nftElement.address.toLowerCase() === nft.address.toLowerCase() &&
303
+ nftElement.tokenId === nft.tokenId);
304
+ });
308
305
  nftMetadataResults.forEach((singleNft) => {
309
- const existingEntry = stateNfts.find((nft) => nft.address.toLowerCase() === singleNft.nft.address.toLowerCase() &&
310
- nft.tokenId === singleNft.nft.tokenId);
311
- if (existingEntry) {
306
+ const existingEntry = stateNfts.find((nft) => nft?.address.toLowerCase() ===
307
+ singleNft.nft.address.toLowerCase() &&
308
+ nft?.tokenId === singleNft.nft.tokenId);
309
+ if (existingEntry && singleNft.newMetadata) {
312
310
  const differentMetadata = compareNftMetadata(singleNft.newMetadata, existingEntry);
313
311
  if (differentMetadata) {
314
- nftsWithDifferentMetadata.push(singleNft);
312
+ nftsWithDifferentMetadata.push({
313
+ nft: singleNft.nft,
314
+ newMetadata: singleNft.newMetadata,
315
+ });
315
316
  }
316
317
  }
317
318
  });
318
319
  if (nftsWithDifferentMetadata.length !== 0) {
319
- nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.nft, elm.newMetadata, addressToSearch, chainId));
320
+ nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.nft, elm.newMetadata, addressToSearch, toHex(elm.nft.chainId)));
320
321
  }
321
322
  }
322
323
  finally {
@@ -328,13 +329,13 @@ export class NftController extends BaseController {
328
329
  *
329
330
  * @param address - Hex address of the NFT contract.
330
331
  * @param tokenId - Token identifier of the NFT.
332
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
331
333
  * @param options - an object of arguments
332
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
333
334
  * @param options.userAddress - The address of the account where the NFT is being removed.
334
335
  */
335
- removeNft(address, tokenId, { networkClientId, userAddress, } = {}) {
336
+ removeNft(address, tokenId, networkClientId, { userAddress } = {}) {
336
337
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
337
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
338
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
338
339
  const checksumHexAddress = toChecksumHexAddress(address);
339
340
  __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_removeIndividualNft).call(this, checksumHexAddress, tokenId, {
340
341
  chainId,
@@ -355,13 +356,13 @@ export class NftController extends BaseController {
355
356
  *
356
357
  * @param address - Hex address of the NFT contract.
357
358
  * @param tokenId - Token identifier of the NFT.
359
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
358
360
  * @param options - an object of arguments
359
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
360
361
  * @param options.userAddress - The address of the account where the NFT is being removed.
361
362
  */
362
- removeAndIgnoreNft(address, tokenId, { networkClientId, userAddress, } = {}) {
363
+ removeAndIgnoreNft(address, tokenId, networkClientId, { userAddress } = {}) {
363
364
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
364
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
365
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
365
366
  const checksumHexAddress = toChecksumHexAddress(address);
366
367
  __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_removeAndIgnoreIndividualNft).call(this, checksumHexAddress, tokenId, {
367
368
  chainId,
@@ -391,20 +392,18 @@ export class NftController extends BaseController {
391
392
  *
392
393
  * @param nft - The NFT object to check and update.
393
394
  * @param batch - A boolean indicating whether this method is being called as part of a batch or single update.
395
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
394
396
  * @param accountParams - The userAddress and chainId to check ownership against
395
397
  * @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure assets are stored to the correct account
396
- * @param accountParams.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
397
398
  * @returns the NFT with the updated isCurrentlyOwned value
398
399
  */
399
- async checkAndUpdateSingleNftOwnershipStatus(nft, batch, { userAddress, networkClientId, } = {}) {
400
+ async checkAndUpdateSingleNftOwnershipStatus(nft, batch, networkClientId, { userAddress } = {}) {
400
401
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
401
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
402
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
402
403
  const { address, tokenId } = nft;
403
404
  let isOwned = nft.isCurrentlyOwned;
404
405
  try {
405
- isOwned = await this.isNftOwner(addressToSearch, address, tokenId, {
406
- networkClientId,
407
- });
406
+ isOwned = await this.isNftOwner(addressToSearch, address, tokenId, networkClientId);
408
407
  }
409
408
  catch {
410
409
  // ignore error
@@ -440,18 +439,18 @@ export class NftController extends BaseController {
440
439
  /**
441
440
  * Checks whether NFTs associated with current selectedAddress/chainId combination are still owned by the user
442
441
  * And updates the isCurrentlyOwned value on each accordingly.
442
+ *
443
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
443
444
  * @param options - an object of arguments
444
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
445
445
  * @param options.userAddress - The address of the account where the NFT ownership status is checked/updated.
446
446
  */
447
- async checkAndUpdateAllNftsOwnershipStatus({ networkClientId, userAddress, } = {}) {
447
+ async checkAndUpdateAllNftsOwnershipStatus(networkClientId, { userAddress, } = {}) {
448
448
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
449
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
449
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
450
450
  const { allNfts } = this.state;
451
451
  const nfts = allNfts[addressToSearch]?.[chainId] || [];
452
452
  const updatedNfts = await Promise.all(nfts.map(async (nft) => {
453
- return ((await this.checkAndUpdateSingleNftOwnershipStatus(nft, true, {
454
- networkClientId,
453
+ return ((await this.checkAndUpdateSingleNftOwnershipStatus(nft, true, networkClientId, {
455
454
  userAddress,
456
455
  })) ?? nft);
457
456
  }));
@@ -466,13 +465,13 @@ export class NftController extends BaseController {
466
465
  * @param address - Hex address of the NFT contract.
467
466
  * @param tokenId - Hex address of the NFT contract.
468
467
  * @param favorite - NFT new favorite status.
468
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
469
469
  * @param options - an object of arguments
470
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
471
470
  * @param options.userAddress - The address of the account where the NFT is being removed.
472
471
  */
473
- updateNftFavoriteStatus(address, tokenId, favorite, { networkClientId, userAddress, } = {}) {
472
+ updateNftFavoriteStatus(address, tokenId, favorite, networkClientId, { userAddress, } = {}) {
474
473
  const addressToSearch = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getAddressOrSelectedAddress).call(this, userAddress);
475
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
474
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
476
475
  const { allNfts } = this.state;
477
476
  const nfts = [...(allNfts[addressToSearch]?.[chainId] || [])];
478
477
  const index = nfts.findIndex((nft) => nft.address === address && nft.tokenId === tokenId);
@@ -615,12 +614,10 @@ export class NftController extends BaseController {
615
614
  });
616
615
  }
617
616
  }
618
- _NftController_mutex = new WeakMap(), _NftController_selectedAccountId = new WeakMap(), _NftController_chainId = new WeakMap(), _NftController_ipfsGateway = new WeakMap(), _NftController_openSeaEnabled = new WeakMap(), _NftController_useIpfsSubdomains = new WeakMap(), _NftController_isIpfsGatewayEnabled = new WeakMap(), _NftController_onNftAdded = new WeakMap(), _NftController_instances = new WeakSet(), _NftController_onNetworkControllerNetworkDidChange = function _NftController_onNetworkControllerNetworkDidChange({ selectedNetworkClientId, }) {
619
- const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
620
- __classPrivateFieldSet(this, _NftController_chainId, chainId, "f");
621
- }, _NftController_onPreferencesControllerStateChange =
617
+ _NftController_mutex = new WeakMap(), _NftController_selectedAccountId = new WeakMap(), _NftController_ipfsGateway = new WeakMap(), _NftController_openSeaEnabled = new WeakMap(), _NftController_useIpfsSubdomains = new WeakMap(), _NftController_isIpfsGatewayEnabled = new WeakMap(), _NftController_onNftAdded = new WeakMap(), _NftController_instances = new WeakSet(), _NftController_onPreferencesControllerStateChange =
622
618
  /**
623
619
  * Handles the state change of the preference controller.
620
+ *
624
621
  * @param preferencesState - The new state of the preference controller.
625
622
  * @param preferencesState.ipfsGateway - The configured IPFS gateway.
626
623
  * @param preferencesState.openSeaEnabled - Controls whether the OpenSea API is used.
@@ -644,6 +641,7 @@ async function _NftController_onPreferencesControllerStateChange({ ipfsGateway,
644
641
  }, _NftController_onSelectedAccountChange =
645
642
  /**
646
643
  * Handles the selected account change on the accounts controller.
644
+ *
647
645
  * @param internalAccount - The new selected account.
648
646
  */
649
647
  async function _NftController_onSelectedAccountChange(internalAccount) {
@@ -866,9 +864,7 @@ async function _NftController_getNftURIAndStandard(contractAddress, tokenId, net
866
864
  * @returns Promise resolving to the current NFT name and image.
867
865
  */
868
866
  async function _NftController_getNftInformation(contractAddress, tokenId, networkClientId) {
869
- const chainId = __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, {
870
- networkClientId,
871
- });
867
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
872
868
  const [blockchainMetadata, nftApiMetadata] = await Promise.all([
873
869
  safelyExecute(() => __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getNftInformationFromTokenURI).call(this, contractAddress, tokenId, networkClientId)),
874
870
  __classPrivateFieldGet(this, _NftController_openSeaEnabled, "f") && chainId === '0x1'
@@ -893,7 +889,9 @@ async function _NftController_getNftInformation(contractAddress, tokenId, networ
893
889
  * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
894
890
  * @returns Promise resolving to the current NFT name and image.
895
891
  */
896
- async function _NftController_getNftContractInformationFromContract(contractAddress, networkClientId) {
892
+ async function _NftController_getNftContractInformationFromContract(
893
+ // TODO for calls to blockchain we need to explicitly pass the currentNetworkClientId since its relying on the provider
894
+ contractAddress, networkClientId) {
897
895
  const [name, symbol] = await Promise.all([
898
896
  this.messagingSystem.call('AssetsContractController:getERC721AssetName', contractAddress, networkClientId),
899
897
  this.messagingSystem.call('AssetsContractController:getERC721AssetSymbol', contractAddress, networkClientId),
@@ -1028,22 +1026,20 @@ async function _NftController_addIndividualNft(tokenAddress, tokenId, nftMetadat
1028
1026
  /**
1029
1027
  * Adds an NFT contract to the stored NFT contracts list.
1030
1028
  *
1029
+ * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request.
1031
1030
  * @param options - options.
1032
1031
  * @param options.tokenAddress - Hex address of the NFT contract.
1033
1032
  * @param options.userAddress - The address of the account where the NFT is being added.
1034
1033
  * @param options.nftMetadata - The retrieved NFTMetadata from API.
1035
- * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
1036
1034
  * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
1037
- * @param options.chainIdHex - The chainId to add the NFT contract to.
1038
1035
  * @returns Promise resolving to the current NFT contracts list.
1039
1036
  */
1040
- async function _NftController_addNftContract({ tokenAddress, userAddress, networkClientId, source, nftMetadata, chainIdHex, }) {
1037
+ async function _NftController_addNftContract(networkClientId, { tokenAddress, userAddress, source, nftMetadata, }) {
1041
1038
  const releaseLock = await __classPrivateFieldGet(this, _NftController_mutex, "f").acquire();
1042
1039
  try {
1043
1040
  const checksumHexAddress = toChecksumHexAddress(tokenAddress);
1044
1041
  const { allNftContracts } = this.state;
1045
- // TODO: revisit this with Solana support and instead of passing chainId, make sure chainId is read from nftMetadata when nftMetadata is available
1046
- const chainId = chainIdHex || __classPrivateFieldGet(this, _NftController_instances, "m", _NftController_getCorrectChainId).call(this, { networkClientId });
1042
+ const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
1047
1043
  const nftContracts = allNftContracts[userAddress]?.[chainId] || [];
1048
1044
  const existingEntry = nftContracts.find((nftContract) => nftContract.address.toLowerCase() ===
1049
1045
  checksumHexAddress.toLowerCase());
@@ -1137,7 +1133,7 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
1137
1133
  userAddress,
1138
1134
  });
1139
1135
  return newNftContracts;
1140
- }, _NftController_validateWatchNft = async function _NftController_validateWatchNft(asset, type, userAddress, { networkClientId } = {}) {
1136
+ }, _NftController_validateWatchNft = async function _NftController_validateWatchNft(asset, type, userAddress, networkClientId) {
1141
1137
  const { address: contractAddress, tokenId } = asset;
1142
1138
  // Validate parameters
1143
1139
  if (!type) {
@@ -1160,7 +1156,7 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
1160
1156
  }
1161
1157
  // Check if the user owns the suggested NFT
1162
1158
  try {
1163
- const isOwner = await this.isNftOwner(userAddress, contractAddress, tokenId, { networkClientId });
1159
+ const isOwner = await this.isNftOwner(userAddress, contractAddress, tokenId, networkClientId);
1164
1160
  if (!isOwner) {
1165
1161
  throw rpcErrors.invalidInput('Suggested NFT is not owned by the selected account');
1166
1162
  }
@@ -1172,12 +1168,6 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
1172
1168
  }
1173
1169
  throw error;
1174
1170
  }
1175
- }, _NftController_getCorrectChainId = function _NftController_getCorrectChainId({ networkClientId, }) {
1176
- if (networkClientId) {
1177
- const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
1178
- return chainId;
1179
- }
1180
- return __classPrivateFieldGet(this, _NftController_chainId, "f");
1181
1171
  }, _NftController_getAddressOrSelectedAddress = function _NftController_getAddressOrSelectedAddress(address) {
1182
1172
  if (address) {
1183
1173
  return address;
@@ -1185,8 +1175,16 @@ async function _NftController_addNftContract({ tokenAddress, userAddress, networ
1185
1175
  // If the address is not defined (or empty), we fallback to the currently selected account's address
1186
1176
  const selectedAccount = this.messagingSystem.call('AccountsController:getAccount', __classPrivateFieldGet(this, _NftController_selectedAccountId, "f"));
1187
1177
  return selectedAccount?.address || '';
1188
- }, _NftController_updateNftUpdateForAccount = async function _NftController_updateNftUpdateForAccount(account) {
1189
- const nfts = this.state.allNfts[account.address]?.[__classPrivateFieldGet(this, _NftController_chainId, "f")] ?? [];
1178
+ }, _NftController_updateNftUpdateForAccount =
1179
+ /**
1180
+ * Updates the all nfts in state for the account.
1181
+ * Nfts will be updated if they don't have a name, description or image.
1182
+ *
1183
+ * @param account - The account to update the NFT metadata for.
1184
+ */
1185
+ async function _NftController_updateNftUpdateForAccount(account) {
1186
+ // get all nfts for the account for all chains
1187
+ const nfts = Object.values(this.state.allNfts[account.address] || {}).flat();
1190
1188
  // Filter only nfts
1191
1189
  const nftsToUpdate = nfts.filter((singleNft) => !singleNft.name && !singleNft.description && !singleNft.image);
1192
1190
  if (nftsToUpdate.length !== 0 &&