Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add updateNft fct #4008

Merged
merged 2 commits into from
Mar 18, 2024
Merged

fix: add updateNft fct #4008

merged 2 commits into from
Mar 18, 2024

Conversation

sahar-fehri
Copy link
Contributor

@sahar-fehri sahar-fehri commented Mar 4, 2024

Explanation

When a user imports an NFT when the display NFT media toggle is off and IPFS toggle is off, then enables the toggles, the image of the NFT will not be displayed.

This PR adds a new fct that fetches the NFT metadata and udpates the state. This fct will be called from extension based on the toggles and if the name/description/image attributes are null

References

  • Related to extension PR #67890

Changelog

@metamask/assets-controllers

  • ADDED: Added new fct updateNftMetadata that fetches nft metadata and updates the state

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

Copy link
Contributor

@MajorLift MajorLift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi great work here! I had a few suggestions for improving typing.

Comment on lines 1530 to 1533
// lib.es2020.promise.d.ts does not export its types so we're using a simple type.
const success = nftMetadataResults.filter(
(promise) => promise.status === 'fulfilled',
) as { status: 'fulfilled'; value: NftUpdate }[];
Copy link
Contributor

@MajorLift MajorLift Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type assertion is avoidable by using a type guard as the predicate for the filter operation.

This allows the compiler to narrow down to PromiseFulfilledResult at the type level.

Suggested change
// lib.es2020.promise.d.ts does not export its types so we're using a simple type.
const success = nftMetadataResults.filter(
(promise) => promise.status === 'fulfilled',
) as { status: 'fulfilled'; value: NftUpdate }[];
const success = nftMetadataResults.filter(
(result): result is PromiseFulfilledResult<NftUpdate> =>
result.status === 'fulfilled',
);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's nice thnx! 🙏

Comment on lines 3574 to 3576
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.stub(nftController, 'getNftInformation' as any)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any is unnecessary here since the compiler tells us exactly what the as assertion target type should be

Argument of type '"getNftInformation"' is not assignable to parameter of type 'keyof NftController'.ts(2345)

Suggested change
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.stub(nftController, 'getNftInformation' as any)
.stub(nftController, 'getNftInformation' as keyof typeof nftController)

In general, shared libraries is trying to avoid introducing new any types except under a few very limited circumstances. An as assertion even to an approximate type is always preferred.

userAddress = this.config.selectedAddress,
) {
const chainId = this.getCorrectChainId({ networkClientId });
const nftsWithChecksumAdr = nfts.map((nft: Nft) => {
Copy link
Contributor

@MajorLift MajorLift Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Type annotations should be avoided unless they narrow an inferred type. There's an entry in the new TypeScript guidelines that covers this topic.

Suggested change
const nftsWithChecksumAdr = nfts.map((nft: Nft) => {
const nftsWithChecksumAdr = nfts.map((nft) => {

packages/assets-controllers/src/NftController.ts Outdated Show resolved Hide resolved
packages/assets-controllers/src/NftController.test.ts Outdated Show resolved Hide resolved
packages/assets-controllers/src/NftController.test.ts Outdated Show resolved Hide resolved
packages/assets-controllers/src/NftController.test.ts Outdated Show resolved Hide resolved
packages/assets-controllers/src/NftController.test.ts Outdated Show resolved Hide resolved
packages/assets-controllers/src/NftController.test.ts Outdated Show resolved Hide resolved
Comment on lines 1530 to 1544
// lib.es2020.promise.d.ts does not export its types so we're using a simple type.
const success = nftMetadataResults.filter(
(promise) => promise.status === 'fulfilled',
) as { status: 'fulfilled'; value: NftUpdate }[];

if (success.length !== 0) {
success.map((elm) =>
this.updateNft(
elm.value.nft,
elm.value.newMetadata,
userAddress,
chainId,
),
);
}
Copy link
Contributor

@MajorLift MajorLift Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Follow-up from #4008 (comment))

Nit: This could be refactored to be more concise.

I also prefer forEach here instead of map to prevent confusion, since the return value is not being used and the updateNft operation relies on side effects.

Suggested change
// lib.es2020.promise.d.ts does not export its types so we're using a simple type.
const success = nftMetadataResults.filter(
(promise) => promise.status === 'fulfilled',
) as { status: 'fulfilled'; value: NftUpdate }[];
if (success.length !== 0) {
success.map((elm) =>
this.updateNft(
elm.value.nft,
elm.value.newMetadata,
userAddress,
chainId,
),
);
}
nftMetadataResults
.filter(
(result): result is PromiseFulfilledResult<NftUpdate> =>
result.status === 'fulfilled',
)
.forEach((elm) =>
this.updateNft(
elm.value.nft,
elm.value.newMetadata,
userAddress,
chainId,
),
);

Copy link
Contributor

@MajorLift MajorLift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@sahar-fehri sahar-fehri force-pushed the fix/fix-import-nft-when-toggle-off branch from e583a68 to 4476447 Compare March 18, 2024 17:26
@sahar-fehri sahar-fehri merged commit b1e0191 into main Mar 18, 2024
139 checks passed
@sahar-fehri sahar-fehri deleted the fix/fix-import-nft-when-toggle-off branch March 18, 2024 17:34
@sahar-fehri sahar-fehri mentioned this pull request Mar 18, 2024
sahar-fehri added a commit that referenced this pull request Mar 19, 2024
This is the release candidate for 128.0.0. It adds a new function on
nftController to update the nft metadata.
#4008
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants