diff --git a/packages/assets-controllers/src/NftController.test.ts b/packages/assets-controllers/src/NftController.test.ts index dc9c9a4a8f..49e48178c7 100644 --- a/packages/assets-controllers/src/NftController.test.ts +++ b/packages/assets-controllers/src/NftController.test.ts @@ -4471,6 +4471,49 @@ describe('NftController', () => { }); describe('updateNftMetadata', () => { + it('should not update Nft metadata when preferences change and current and incoming state are the same', async () => { + const { + nftController, + triggerPreferencesStateChange, + triggerSelectedAccountChange, + } = setupController(); + const spy = jest.spyOn(nftController, 'updateNftMetadata'); + triggerSelectedAccountChange(OWNER_ACCOUNT); + // trigger preference change + triggerPreferencesStateChange({ + ...getDefaultPreferencesState(), + }); + + expect(spy).toHaveBeenCalledTimes(0); + }); + + it('should call update Nft metadata when preferences change is triggered and at least ipfsGateway, openSeaEnabled or isIpfsGatewayEnabled change', async () => { + const { + nftController, + mockGetAccount, + triggerPreferencesStateChange, + triggerSelectedAccountChange, + } = setupController({ + defaultSelectedAccount: OWNER_ACCOUNT, + }); + const spy = jest.spyOn(nftController, 'updateNftMetadata'); + const testNetworkClientId = 'mainnet'; + mockGetAccount.mockReturnValue(OWNER_ACCOUNT); + await nftController.addNft('0xtest', '3', { + nftMetadata: { name: '', description: '', image: '', standard: '' }, + networkClientId: testNetworkClientId, + }); + + triggerSelectedAccountChange(OWNER_ACCOUNT); + // trigger preference change + triggerPreferencesStateChange({ + ...getDefaultPreferencesState(), + ipfsGateway: 'https://toto/ipfs/', + }); + + expect(spy).toHaveBeenCalledTimes(1); + }); + it('should update Nft metadata successfully', async () => { const tokenURI = 'https://api.pudgypenguins.io/lil/4'; const mockGetERC721TokenURI = jest.fn().mockResolvedValue(tokenURI); diff --git a/packages/assets-controllers/src/NftController.ts b/packages/assets-controllers/src/NftController.ts index df159b91a9..292611dc0d 100644 --- a/packages/assets-controllers/src/NftController.ts +++ b/packages/assets-controllers/src/NftController.ts @@ -100,12 +100,11 @@ type SuggestedNftMeta = { * @property isCurrentlyOwned - Boolean indicating whether the address/chainId combination where it's currently stored currently owns this NFT * @property transactionId - Transaction Id associated with the NFT */ -export type Nft = - | { - tokenId: string; - address: string; - isCurrentlyOwned?: boolean; - } & NftMetadata; +export type Nft = { + tokenId: string; + address: string; + isCurrentlyOwned?: boolean; +} & NftMetadata; type NftUpdate = { nft: Nft; @@ -274,6 +273,8 @@ export const getDefaultNftControllerState = (): NftControllerState => ({ ignoredNfts: [], }); +const NFT_UPDATE_THRESHOLD = 500; + /** * Controller that stores assets and exposes convenience methods */ @@ -421,15 +422,21 @@ export class NftController extends BaseController< 'AccountsController:getSelectedAccount', ); this.#selectedAccountId = selectedAccount.id; - this.#ipfsGateway = ipfsGateway; - this.#openSeaEnabled = openSeaEnabled; - this.#isIpfsGatewayEnabled = isIpfsGatewayEnabled; - - const needsUpdateNftMetadata = - (isIpfsGatewayEnabled && ipfsGateway !== '') || openSeaEnabled; - - if (needsUpdateNftMetadata && selectedAccount) { - await this.#updateNftUpdateForAccount(selectedAccount); + // Get current state values + if ( + this.#ipfsGateway !== ipfsGateway || + this.#openSeaEnabled !== openSeaEnabled || + this.#isIpfsGatewayEnabled !== isIpfsGatewayEnabled + ) { + this.#ipfsGateway = ipfsGateway; + this.#openSeaEnabled = openSeaEnabled; + this.#isIpfsGatewayEnabled = isIpfsGatewayEnabled; + const needsUpdateNftMetadata = + (isIpfsGatewayEnabled && ipfsGateway !== '') || openSeaEnabled; + + if (needsUpdateNftMetadata && selectedAccount) { + await this.#updateNftUpdateForAccount(selectedAccount); + } } } @@ -2053,7 +2060,10 @@ export class NftController extends BaseController< (singleNft) => !singleNft.name && !singleNft.description && !singleNft.image, ); - if (nftsToUpdate.length !== 0) { + if ( + nftsToUpdate.length !== 0 && + nftsToUpdate.length < NFT_UPDATE_THRESHOLD + ) { await this.updateNftMetadata({ nfts: nftsToUpdate, userAddress: account.address,