From 0ba5be6935f47ad9aa6dc279b10bba10c555979a Mon Sep 17 00:00:00 2001 From: Nicole O'Brien Date: Mon, 29 Apr 2024 17:48:19 +0100 Subject: [PATCH 1/3] fix: do not update persisted rpc endpoint recursively (#2389) * fix: do not update persisted rpc endpoint recursively * fix: remove problem line --- .../shared/src/lib/core/network/classes/isc-chain.class.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/shared/src/lib/core/network/classes/isc-chain.class.ts b/packages/shared/src/lib/core/network/classes/isc-chain.class.ts index b2a2c18fee..7774f8fa0e 100644 --- a/packages/shared/src/lib/core/network/classes/isc-chain.class.ts +++ b/packages/shared/src/lib/core/network/classes/isc-chain.class.ts @@ -14,8 +14,7 @@ export class IscChain extends BaseEvmNetwork { try { const { rpcEndpoint, aliasAddress, apiEndpoint } = chainConfiguration const _rpcEndpoint = `${rpcEndpoint}/v1/chains/${aliasAddress}/evm` - chainConfiguration.rpcEndpoint = _rpcEndpoint - super(chainConfiguration) + super({ ...chainConfiguration, rpcEndpoint: _rpcEndpoint }) this.aliasAddress = aliasAddress this.apiEndpoint = apiEndpoint From a5681bc65e2501897798ba6a5d5c6471205b5af0 Mon Sep 17 00:00:00 2001 From: Mark Nardi Date: Mon, 29 Apr 2024 19:04:37 +0200 Subject: [PATCH 2/3] fix: remove duplicated ownership check (#2393) * filter for network on ownership check * disable feature flag --- packages/desktop/features/network.features.ts | 2 +- .../src/lib/core/layer-2/actions/fetchL2BalanceForAccount.ts | 2 +- .../src/lib/core/nfts/actions/updateErc721NftOwnership.ts | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/desktop/features/network.features.ts b/packages/desktop/features/network.features.ts index 7cf79283c1..2d49c92cb9 100644 --- a/packages/desktop/features/network.features.ts +++ b/packages/desktop/features/network.features.ts @@ -12,7 +12,7 @@ const networkFeatures: INetworkFeatures = { }, }, evmNetworks: { - enabled: true, + enabled: false, }, } diff --git a/packages/shared/src/lib/core/layer-2/actions/fetchL2BalanceForAccount.ts b/packages/shared/src/lib/core/layer-2/actions/fetchL2BalanceForAccount.ts index a0102ef16b..758584959b 100644 --- a/packages/shared/src/lib/core/layer-2/actions/fetchL2BalanceForAccount.ts +++ b/packages/shared/src/lib/core/layer-2/actions/fetchL2BalanceForAccount.ts @@ -23,7 +23,7 @@ export function fetchL2BalanceForAccount(profileId: string, account: IAccountSta } if (features.collectibles.erc721.enabled) { - void updateErc721NftsOwnership(account) + void updateErc721NftsOwnership(account, evmNetwork.id) } const l2TokenBalance = isIscChain(evmNetwork) diff --git a/packages/shared/src/lib/core/nfts/actions/updateErc721NftOwnership.ts b/packages/shared/src/lib/core/nfts/actions/updateErc721NftOwnership.ts index cee6632566..b3c65cd83c 100644 --- a/packages/shared/src/lib/core/nfts/actions/updateErc721NftOwnership.ts +++ b/packages/shared/src/lib/core/nfts/actions/updateErc721NftOwnership.ts @@ -5,12 +5,13 @@ import { IErc721Nft } from '../interfaces' import { getAllAccountNfts, persistedNftForActiveProfile, updatePersistedNft } from '../stores' import { getOwnerOfErc721Nft } from '../utils' import { get } from 'svelte/store' +import { NetworkId } from '@core/network' -export async function updateErc721NftsOwnership(account: IAccountState): Promise { +export async function updateErc721NftsOwnership(account: IAccountState, networkId: NetworkId): Promise { try { const trackedErc721Nfts = (getAllAccountNfts()[account.index]?.filter((nft) => { - return nft.standard === NftStandard.Erc721 + return nft.standard === NftStandard.Erc721 && nft.networkId === networkId }) as IErc721Nft[]) ?? [] const promises = trackedErc721Nfts.map(async (nft) => { const updatedOwner = await getOwnerOfErc721Nft(nft) From 9711f05ceb5339360e9ad523b8d70700710341e4 Mon Sep 17 00:00:00 2001 From: Jean Ribeiro Date: Mon, 29 Apr 2024 15:20:54 -0300 Subject: [PATCH 3/3] feat: adds collection data in CollectionsGalleryView (#2391) * feat: adds collection data in CollectionsGalleryView * enhancement: getCollectionFromNft * chore: remove unnnecessary console errors * fix: not visible collections --- .../views/CollectionsGalleryView.svelte | 42 +++++++------- .../nfts/interfaces/collection.interface.ts | 10 ++++ .../src/lib/core/nfts/interfaces/index.ts | 1 + .../lib/core/nfts/interfaces/nft.interface.ts | 3 +- .../shared/src/lib/core/nfts/stores/index.ts | 1 + .../selected-account-collections.store.ts | 58 +++++++++++++++++++ .../lib/core/nfts/types/collections.type.ts | 3 + .../shared/src/lib/core/nfts/types/index.ts | 1 + .../core/nfts/utils/getCollectionFromNft.ts | 42 ++++++++++++++ .../shared/src/lib/core/nfts/utils/index.ts | 10 ++-- .../core/nfts/utils/isVisibleCollection.ts | 20 +++++++ 11 files changed, 164 insertions(+), 27 deletions(-) create mode 100644 packages/shared/src/lib/core/nfts/interfaces/collection.interface.ts create mode 100644 packages/shared/src/lib/core/nfts/stores/selected-account-collections.store.ts create mode 100644 packages/shared/src/lib/core/nfts/types/collections.type.ts create mode 100644 packages/shared/src/lib/core/nfts/utils/getCollectionFromNft.ts create mode 100644 packages/shared/src/lib/core/nfts/utils/isVisibleCollection.ts diff --git a/packages/desktop/views/dashboard/collectibles/views/CollectionsGalleryView.svelte b/packages/desktop/views/dashboard/collectibles/views/CollectionsGalleryView.svelte index e95024b661..28f84f689d 100644 --- a/packages/desktop/views/dashboard/collectibles/views/CollectionsGalleryView.svelte +++ b/packages/desktop/views/dashboard/collectibles/views/CollectionsGalleryView.svelte @@ -1,13 +1,13 @@ @@ -35,23 +33,25 @@
{localize('views.collectibles.collectionsGallery.title')} - {String(queriedCollections.length ?? '')} + {String(Object.keys($selectedAccountCollections).length ?? '')}
- {#if collections.length} - - + {#if hasCollections} + {/if} {#if features.collectibles.erc721.enabled} {/if}
- {#if collections.length} - {#if queriedCollections.length} + {#if hasCollections} + {#if Object.keys(queriedCollections).length > 0} + {#each Object.keys(queriedCollections) as collection} + {queriedCollections[collection].name} + {/each} {:else}
= writable({}) + +async function updateCollections(nfts: Nft[]): Promise { + const existingCollections = get(collectionsStore) + + if (nfts.length === 0) { + if (Object.keys(existingCollections).length > 0) { + collectionsStore.set({}) + } + return + } + + const collectionsUpdate = { ...existingCollections } + + await Promise.all( + nfts.map(async (nft) => { + if (nft.standard !== NftStandard.Irc27 || !nft.issuer) { + return + } + + const issuerId = nft.issuer.aliasId ?? nft.issuer.nftId + if (!issuerId) { + return + } + + if (!collectionsUpdate[issuerId]) { + const collection = await getCollectionFromNft(nft) + if (collection) { + collectionsUpdate[issuerId] = { ...collection, nfts: [nft] } + } + } else { + const existingNfts = collectionsUpdate[issuerId].nfts + if (!existingNfts.find((existingNft) => existingNft.id === nft.id)) { + collectionsUpdate[issuerId].nfts.push(nft) + } + } + }) + ) + collectionsStore.set(collectionsUpdate) +} + +selectedAccountNfts.subscribe((nfts) => { + void updateCollections(nfts) +}) + +export const selectedAccountCollections: Readable = derived( + collectionsStore, + ($collectionsStore) => $collectionsStore +) + +export const collectionsSearchTerm: Writable = writable('') diff --git a/packages/shared/src/lib/core/nfts/types/collections.type.ts b/packages/shared/src/lib/core/nfts/types/collections.type.ts new file mode 100644 index 0000000000..32dae6f7df --- /dev/null +++ b/packages/shared/src/lib/core/nfts/types/collections.type.ts @@ -0,0 +1,3 @@ +import { Collection } from '../interfaces' + +export type Collections = { [key: string]: Collection } diff --git a/packages/shared/src/lib/core/nfts/types/index.ts b/packages/shared/src/lib/core/nfts/types/index.ts index 3d34a70382..77e3cbecb6 100644 --- a/packages/shared/src/lib/core/nfts/types/index.ts +++ b/packages/shared/src/lib/core/nfts/types/index.ts @@ -1,2 +1,3 @@ +export * from './collections.type' export * from './nft-download-options.type' export * from './persisted-nft.type' diff --git a/packages/shared/src/lib/core/nfts/utils/getCollectionFromNft.ts b/packages/shared/src/lib/core/nfts/utils/getCollectionFromNft.ts new file mode 100644 index 0000000000..232f4d632e --- /dev/null +++ b/packages/shared/src/lib/core/nfts/utils/getCollectionFromNft.ts @@ -0,0 +1,42 @@ +import { NftStandard } from '../enums' +import { Collection, Nft } from '../interfaces' +import { Converter } from '@core/utils' +import { getClient } from '@core/profile-manager' +import type { AliasOutput, MetadataFeature, NftOutput } from '@iota/sdk' +import { FeatureType } from '@iota/sdk/out/types' + +export async function getCollectionFromNft(nft: Nft): Promise { + if (nft.standard !== NftStandard.Irc27) { + return + } + + const { aliasId = '', nftId = '' } = nft.issuer ?? {} + if (!aliasId && !nftId) { + return + } + + try { + const client = await getClient() + const outputId = aliasId ? await client.aliasOutputId(aliasId) : await client.nftOutputId(nftId) + if (!outputId) { + return + } + + const outputResponse = await client.getOutput(outputId) + const output = outputResponse.output as AliasOutput | NftOutput + + const metadataFeature = output.immutableFeatures?.find( + (feature) => feature.type === FeatureType.Metadata + ) as MetadataFeature + + if (!metadataFeature?.data) { + return + } + + const { standard, name, type, uri } = JSON.parse(Converter.hexToUtf8(metadataFeature.data)) + + return { standard, name, type, uri, nfts: [] } + } catch (error) { + console.error('Error retrieving collection from NFT:', error) + } +} diff --git a/packages/shared/src/lib/core/nfts/utils/index.ts b/packages/shared/src/lib/core/nfts/utils/index.ts index 93e479f6d5..f8305f6b34 100644 --- a/packages/shared/src/lib/core/nfts/utils/index.ts +++ b/packages/shared/src/lib/core/nfts/utils/index.ts @@ -1,17 +1,19 @@ export * from './buildNftFromPersistedErc721Nft' +export * from './buildPersistedErc721Nft' export * from './checkIfNftShouldBeDownloaded' +export * from './fetchWithTimeout' +export * from './getCollectionFromNft' +export * from './getFetchableNftUrls' export * from './getFilePathForNft' export * from './getNftsFromNftIds' export * from './getOwnerOfErc721Nft' -export * from './buildPersistedErc721Nft' -export * from './getFetchableNftUrls' export * from './getPrimaryNftUrl' export * from './getSpendableStatusFromUnspentNftOutput' -export * from './fetchWithTimeout' export * from './isIrc27Nft' -export * from './isNftOwnedByAnyAccount' export * from './isNftLocked' +export * from './isNftOwnedByAnyAccount' export * from './isScamIrc27Nft' export * from './isValidNftUri' +export * from './isVisibleCollection' export * from './isVisibleNft' export * from './parseNftMetadata' diff --git a/packages/shared/src/lib/core/nfts/utils/isVisibleCollection.ts b/packages/shared/src/lib/core/nfts/utils/isVisibleCollection.ts new file mode 100644 index 0000000000..6c367e4cbd --- /dev/null +++ b/packages/shared/src/lib/core/nfts/utils/isVisibleCollection.ts @@ -0,0 +1,20 @@ +import { get } from 'svelte/store' +import { collectionsSearchTerm } from '../stores' +import { Collection } from '../interfaces' + +export function isVisibleCollection(collection: Collection): boolean { + const searchTerm = get(collectionsSearchTerm) + + if (!isVisibleWithSearchTerm(collection, searchTerm)) { + return false + } + + return true +} + +function isVisibleWithSearchTerm(collection: Collection, searchTerm: string): boolean { + if (searchTerm) { + return collection.name.toLowerCase().includes(searchTerm.toLowerCase()) + } + return true +}