@metamask-previews/assets-controllers 65.0.0-preview-e5f15167 → 65.0.0-preview-9ae2ce46

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