Skip to content

Commit b43f657

Browse files
authored
chore: explicitly pass chainIds to detectNfts (#5448)
## Explanation PR updates detectNfts function to explicitly receive an array of chainIds to detectNfts for. ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? For example: * Fixes #12345 * Related to #67890 --> ## Changelog <!-- If you're making any consumer-facing changes, list those changes here as if you were updating a changelog, using the template below as a guide. (CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or FIXED. For security-related issues, follow the Security Advisory process.) Please take care to name the exact pieces of the API you've added or changed (e.g. types, interfaces, functions, or methods). If there are any breaking changes, make sure to offer a solution for consumers to follow once they upgrade to the changes. Finally, if you're only making changes to development scripts or tests, you may replace the template below with "None". --> ### `@metamask/assets-controllers` - **BREAKING**: `detectNfts` fct now accepts chainIds as a new arg - **REMOVED**: Removed `networkClientId` as an optional param in `detectNfts` fct in favor of new `chainIds` required arg. - **ADDED**: `addNft` fct now accepts chainId as an additional optional param ## Checklist - [ ] I've updated the test suite for new or updated code as appropriate - [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [ ] I've highlighted breaking changes using the "BREAKING" category above as appropriate - [ ] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
1 parent bcb3225 commit b43f657

File tree

5 files changed

+345
-137
lines changed

5 files changed

+345
-137
lines changed

packages/assets-controllers/src/NftController.test.ts

+40
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
NetworksTicker,
2020
NFT_API_BASE_URL,
2121
InfuraNetworkType,
22+
convertHexToDecimal,
2223
} from '@metamask/controller-utils';
2324
import type { InternalAccount } from '@metamask/keyring-internal-api';
2425
import type {
@@ -1239,6 +1240,7 @@ describe('NftController', () => {
12391240
image: 'testERC721Image',
12401241
name: 'testERC721Name',
12411242
standard: ERC721,
1243+
chainId: convertHexToDecimal(ChainId.goerli),
12421244
},
12431245
],
12441246
},
@@ -1348,6 +1350,7 @@ describe('NftController', () => {
13481350
image: 'testERC721Image',
13491351
name: 'testERC721Name',
13501352
standard: ERC721,
1353+
chainId: convertHexToDecimal(ChainId.goerli),
13511354
},
13521355
],
13531356
},
@@ -1408,6 +1411,7 @@ describe('NftController', () => {
14081411
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
14091412
).toStrictEqual({
14101413
address: '0x01',
1414+
chainId: convertHexToDecimal(ChainId.mainnet),
14111415
description: 'description',
14121416
image: 'image',
14131417
name: 'name',
@@ -1539,6 +1543,7 @@ describe('NftController', () => {
15391543
nftController.state.allNfts[firstAddress][ChainId.mainnet][0],
15401544
).toStrictEqual({
15411545
address: '0x01',
1546+
chainId: convertHexToDecimal(ChainId.mainnet),
15421547
description: 'description',
15431548
image: 'url',
15441549
name: 'name',
@@ -1569,6 +1574,7 @@ describe('NftController', () => {
15691574
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
15701575
).toStrictEqual({
15711576
address: '0x01',
1577+
chainId: convertHexToDecimal(ChainId.mainnet),
15721578
description: 'description',
15731579
image: 'image',
15741580
name: 'name',
@@ -1592,6 +1598,7 @@ describe('NftController', () => {
15921598
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
15931599
).toStrictEqual({
15941600
address: '0x01',
1601+
chainId: convertHexToDecimal(ChainId.mainnet),
15951602
description: 'description',
15961603
image: 'image-updated',
15971604
name: 'name',
@@ -1621,6 +1628,7 @@ describe('NftController', () => {
16211628
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
16221629
).toStrictEqual({
16231630
address: '0x01',
1631+
chainId: convertHexToDecimal(ChainId.mainnet),
16241632
description: 'description',
16251633
image: 'image',
16261634
name: 'name',
@@ -1649,6 +1657,7 @@ describe('NftController', () => {
16491657
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
16501658
).toStrictEqual({
16511659
address: '0x01',
1660+
chainId: convertHexToDecimal(ChainId.mainnet),
16521661
description: 'description',
16531662
image: 'image',
16541663
name: 'name',
@@ -1693,6 +1702,7 @@ describe('NftController', () => {
16931702
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
16941703
).toStrictEqual({
16951704
address: '0x01',
1705+
chainId: convertHexToDecimal(ChainId.mainnet),
16961706
description: 'description',
16971707
image: 'image',
16981708
name: 'name',
@@ -1730,6 +1740,7 @@ describe('NftController', () => {
17301740
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
17311741
).toStrictEqual({
17321742
address: '0x01',
1743+
chainId: convertHexToDecimal(ChainId.mainnet),
17331744
description: 'description',
17341745
image: 'image',
17351746
name: 'name',
@@ -1838,6 +1849,7 @@ describe('NftController', () => {
18381849
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
18391850
).toStrictEqual({
18401851
address: '0x01',
1852+
chainId: convertHexToDecimal(ChainId.mainnet),
18411853
description: 'Description',
18421854
image: 'url',
18431855
name: 'Name',
@@ -1909,6 +1921,7 @@ describe('NftController', () => {
19091921
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
19101922
).toStrictEqual({
19111923
address: ERC721_KUDOSADDRESS,
1924+
chainId: convertHexToDecimal(ChainId.mainnet),
19121925
image: 'url',
19131926
name: 'Kudos Name (directly from tokenURI)',
19141927
description: 'Kudos Description (directly from tokenURI)',
@@ -1998,6 +2011,7 @@ describe('NftController', () => {
19982011
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
19992012
).toStrictEqual({
20002013
address: ERC721_KUDOSADDRESS,
2014+
chainId: convertHexToDecimal(ChainId.mainnet),
20012015
image: 'url',
20022016
name: 'Kudos Name (directly from tokenURI)',
20032017
description: 'Kudos Description (directly from tokenURI)',
@@ -2063,6 +2077,7 @@ describe('NftController', () => {
20632077
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
20642078
).toStrictEqual({
20652079
address: ERC1155_NFT_ADDRESS,
2080+
chainId: convertHexToDecimal(ChainId.mainnet),
20662081
image: 'image (directly from tokenURI)',
20672082
name: 'name (directly from tokenURI)',
20682083
description: 'description (directly from tokenURI)',
@@ -2109,6 +2124,7 @@ describe('NftController', () => {
21092124
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
21102125
).toStrictEqual({
21112126
address: ERC721_KUDOSADDRESS,
2127+
chainId: convertHexToDecimal(ChainId.mainnet),
21122128
image: 'Kudos Image (directly from tokenURI)',
21132129
name: 'Kudos Name (directly from tokenURI)',
21142130
description: 'Kudos Description (directly from tokenURI)',
@@ -2147,6 +2163,7 @@ describe('NftController', () => {
21472163
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
21482164
).toStrictEqual({
21492165
address: ERC721_KUDOSADDRESS,
2166+
chainId: convertHexToDecimal(ChainId.mainnet),
21502167
image: testTokenUriEncoded,
21512168
name: null,
21522169
description: null,
@@ -2188,6 +2205,7 @@ describe('NftController', () => {
21882205
][0],
21892206
).toStrictEqual({
21902207
address: '0x01',
2208+
chainId: convertHexToDecimal(ChainId.sepolia),
21912209
description: 'description',
21922210
image: 'url',
21932211
name: 'name',
@@ -2239,6 +2257,7 @@ describe('NftController', () => {
22392257
[ChainId.mainnet]: [
22402258
{
22412259
address: '0x01234abcdefg',
2260+
chainId: convertHexToDecimal(ChainId.mainnet),
22422261
description: 'description',
22432262
image: 'url',
22442263
name: 'name',
@@ -2303,6 +2322,7 @@ describe('NftController', () => {
23032322
[GOERLI.chainId]: [
23042323
{
23052324
address: '0x01234abcdefg',
2325+
chainId: convertHexToDecimal(ChainId.goerli),
23062326
description: 'description',
23072327
image: 'url',
23082328
name: 'name',
@@ -2396,6 +2416,7 @@ describe('NftController', () => {
23962416
).toStrictEqual([
23972417
{
23982418
address: ERC721_KUDOSADDRESS,
2419+
chainId: convertHexToDecimal(ChainId.mainnet),
23992420
description: 'Kudos Description',
24002421
image: 'Kudos image (from proxy API)',
24012422
name: 'Kudos Name',
@@ -2518,6 +2539,7 @@ describe('NftController', () => {
25182539
).toStrictEqual([
25192540
{
25202541
address: ERC721_KUDOSADDRESS,
2542+
chainId: convertHexToDecimal(ChainId.mainnet),
25212543
description: 'Kudos Description',
25222544
image: 'Kudos image (from proxy API)',
25232545
name: 'Kudos Name',
@@ -2698,6 +2720,7 @@ describe('NftController', () => {
26982720
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
26992721
).toStrictEqual({
27002722
address: ERC721_DEPRESSIONIST_ADDRESS,
2723+
chainId: convertHexToDecimal(ChainId.mainnet),
27012724
tokenId: '36',
27022725
image: 'image',
27032726
name: 'name',
@@ -2724,6 +2747,7 @@ describe('NftController', () => {
27242747
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
27252748
).toStrictEqual({
27262749
address: ERC721_NFT_ADDRESS,
2750+
chainId: convertHexToDecimal(ChainId.mainnet),
27272751
image: null,
27282752
name: null,
27292753
description: null,
@@ -2810,6 +2834,7 @@ describe('NftController', () => {
28102834
).toStrictEqual([
28112835
{
28122836
address: '0x01',
2837+
chainId: convertHexToDecimal(ChainId.sepolia),
28132838
description: 'test-description-1',
28142839
image: 'test-image-1',
28152840
name: 'test-name-1',
@@ -2826,6 +2851,7 @@ describe('NftController', () => {
28262851
).toStrictEqual([
28272852
{
28282853
address: '0x02',
2854+
chainId: convertHexToDecimal(ChainId.goerli),
28292855
description: 'test-description-2',
28302856
image: 'test-image-2',
28312857
name: 'test-name-2',
@@ -2840,6 +2866,7 @@ describe('NftController', () => {
28402866
expect(nftController.state.allNfts[OWNER_ADDRESS]['0xa']).toStrictEqual([
28412867
{
28422868
address: '0x03',
2869+
chainId: convertHexToDecimal('0xa'),
28432870
description: 'test-description-3',
28442871
image: 'test-image-3',
28452872
name: 'test-name-3',
@@ -2926,6 +2953,7 @@ describe('NftController', () => {
29262953
expect(nftController.state.allNfts[userAddress]['0x1']).toStrictEqual([
29272954
{
29282955
address: '0x01',
2956+
chainId: convertHexToDecimal(ChainId.mainnet),
29292957
description: 'test-description-1',
29302958
image: 'test-image-1',
29312959
name: 'test-name-1',
@@ -2941,6 +2969,7 @@ describe('NftController', () => {
29412969
).toStrictEqual([
29422970
{
29432971
address: '0x02',
2972+
chainId: convertHexToDecimal(ChainId.goerli),
29442973
description: 'test-description-2',
29452974
image: 'test-image-2',
29462975
name: 'test-name-2',
@@ -2956,6 +2985,7 @@ describe('NftController', () => {
29562985
).toStrictEqual([
29572986
{
29582987
address: '0x03',
2988+
chainId: convertHexToDecimal(ChainId.sepolia),
29592989
description: 'test-description-3',
29602990
image: 'test-image-3',
29612991
name: 'test-name-3',
@@ -3050,6 +3080,7 @@ describe('NftController', () => {
30503080
nftController.state.allNfts[firstAccount.address][ChainId.mainnet][0],
30513081
).toStrictEqual({
30523082
address: '0x01',
3083+
chainId: convertHexToDecimal(ChainId.mainnet),
30533084
description: 'description',
30543085
image: 'url',
30553086
name: 'name',
@@ -3142,6 +3173,7 @@ describe('NftController', () => {
31423173
nftController.state.allNfts[firstAccount.address][SEPOLIA.chainId][0],
31433174
).toStrictEqual({
31443175
address: '0x01',
3176+
chainId: convertHexToDecimal(ChainId.sepolia),
31453177
description: 'description',
31463178
image: 'url',
31473179
name: 'name',
@@ -3155,6 +3187,7 @@ describe('NftController', () => {
31553187
nftController.state.allNfts[secondAccount.address][GOERLI.chainId][0],
31563188
).toStrictEqual({
31573189
address: '0x02',
3190+
chainId: convertHexToDecimal(ChainId.goerli),
31583191
description: 'description',
31593192
image: 'url',
31603193
name: 'name',
@@ -3210,6 +3243,7 @@ describe('NftController', () => {
32103243
nftController.state.allNfts[firstAddress][SEPOLIA.chainId][0],
32113244
).toStrictEqual({
32123245
address: '0x01',
3246+
chainId: convertHexToDecimal(ChainId.sepolia),
32133247
description: 'description',
32143248
image: 'url',
32153249
name: 'name',
@@ -3223,6 +3257,7 @@ describe('NftController', () => {
32233257
nftController.state.allNfts[secondAddress][GOERLI.chainId][0],
32243258
).toStrictEqual({
32253259
address: '0x02',
3260+
chainId: convertHexToDecimal(ChainId.goerli),
32263261
description: 'description',
32273262
image: 'url',
32283263
name: 'name',
@@ -3345,6 +3380,7 @@ describe('NftController', () => {
33453380
nftController.state.allNfts[firstAccount.address][ChainId.mainnet][0],
33463381
).toStrictEqual({
33473382
address: '0x02',
3383+
chainId: convertHexToDecimal(ChainId.mainnet),
33483384
description: 'description',
33493385
image: 'url',
33503386
name: 'name',
@@ -3384,6 +3420,7 @@ describe('NftController', () => {
33843420
nftController.state.allNfts[OWNER_ACCOUNT.address][SEPOLIA.chainId][0],
33853421
).toStrictEqual({
33863422
address: '0x02',
3423+
chainId: convertHexToDecimal(ChainId.sepolia),
33873424
description: 'description',
33883425
image: 'url',
33893426
name: 'name',
@@ -3436,6 +3473,7 @@ describe('NftController', () => {
34363473
nftController.state.allNfts[userAddress1][SEPOLIA.chainId][0],
34373474
).toStrictEqual({
34383475
address: '0x01',
3476+
chainId: convertHexToDecimal(ChainId.sepolia),
34393477
description: 'description',
34403478
image: 'image',
34413479
name: 'name',
@@ -3638,6 +3676,7 @@ describe('NftController', () => {
36383676
nftController.state.allNfts[OWNER_ACCOUNT.address][ChainId.mainnet][0],
36393677
).toStrictEqual({
36403678
address: ERC1155_NFT_ADDRESS,
3679+
chainId: convertHexToDecimal(ChainId.mainnet),
36413680
name: null,
36423681
description: null,
36433682
image: null,
@@ -4622,6 +4661,7 @@ describe('NftController', () => {
46224661
nftController.state.allNfts[OWNER_ACCOUNT.address][SEPOLIA.chainId][0],
46234662
).toStrictEqual({
46244663
address: '0xtest',
4664+
chainId: convertHexToDecimal(ChainId.sepolia),
46254665
description: 'description',
46264666
favorite: false,
46274667
image: 'image.png',

packages/assets-controllers/src/NftController.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
ApprovalType,
2626
NFT_API_BASE_URL,
2727
NFT_API_VERSION,
28+
convertHexToDecimal,
2829
} from '@metamask/controller-utils';
2930
import { type InternalAccount } from '@metamask/keyring-internal-api';
3031
import type {
@@ -180,6 +181,7 @@ export type NftMetadata = {
180181
lastSale?: LastSale;
181182
rarityRank?: string;
182183
topBid?: TopBid;
184+
chainId?: number;
183185
};
184186

185187
/**
@@ -1494,6 +1496,7 @@ export class NftController extends BaseController<
14941496
* @param options.userAddress - The address of the current user.
14951497
* @param options.source - Whether the NFT was detected, added manually or suggested by a dapp.
14961498
* @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request.
1499+
* @param options.chainId - The chain ID to add the NFT to.
14971500
* @returns Promise resolving to the current NFT list.
14981501
*/
14991502
async addNft(
@@ -1504,11 +1507,13 @@ export class NftController extends BaseController<
15041507
userAddress,
15051508
source = Source.Custom,
15061509
networkClientId,
1510+
chainId,
15071511
}: {
15081512
nftMetadata?: NftMetadata;
15091513
userAddress?: string;
15101514
source?: Source;
15111515
networkClientId?: NetworkClientId;
1516+
chainId?: Hex;
15121517
} = {},
15131518
) {
15141519
const addressToSearch = this.#getAddressOrSelectedAddress(userAddress);
@@ -1518,7 +1523,8 @@ export class NftController extends BaseController<
15181523

15191524
const checksumHexAddress = toChecksumHexAddress(tokenAddress);
15201525

1521-
const chainId = this.#getCorrectChainId({ networkClientId });
1526+
const chainIdToAddTo =
1527+
chainId || this.#getCorrectChainId({ networkClientId });
15221528

15231529
nftMetadata =
15241530
nftMetadata ||
@@ -1541,6 +1547,10 @@ export class NftController extends BaseController<
15411547
(contract) =>
15421548
contract.address.toLowerCase() === checksumHexAddress.toLowerCase(),
15431549
);
1550+
// This is the case when the NFT is added manually and not detected automatically
1551+
if (!nftMetadata.chainId) {
1552+
nftMetadata.chainId = convertHexToDecimal(chainIdToAddTo);
1553+
}
15441554

15451555
// If NFT contract information, add individual NFT
15461556
if (nftContract) {
@@ -1549,7 +1559,7 @@ export class NftController extends BaseController<
15491559
tokenId,
15501560
nftMetadata,
15511561
nftContract,
1552-
chainId,
1562+
chainIdToAddTo,
15531563
addressToSearch,
15541564
source,
15551565
);

0 commit comments

Comments
 (0)