From 38494203e61162211c68da9151499da80cebd0b7 Mon Sep 17 00:00:00 2001 From: Jordi Parra Crespo Date: Fri, 11 Oct 2024 12:48:30 +0200 Subject: [PATCH 1/2] fix: nft not being displayed in the app --- .../display/NftImage/NftImage.styles.ts | 2 +- .../sdk/NearSdkService/NearSdkService.ts | 118 ++++++++++++++---- src/module/sdk/utils/near.constants.ts | 2 + 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/module/nft/component/display/NftImage/NftImage.styles.ts b/src/module/nft/component/display/NftImage/NftImage.styles.ts index 86acf807f..0e12ec24d 100644 --- a/src/module/nft/component/display/NftImage/NftImage.styles.ts +++ b/src/module/nft/component/display/NftImage/NftImage.styles.ts @@ -6,7 +6,7 @@ const NFT_CARD_WIDTH = 112; export const NftImageRoot = styled(Image)(({ theme: { palette: p, borderRadiusXs } }) => ({ borderRadius: borderRadiusXs, - backgroundColor: p.gray[300], + backgroundColor: p.gray[100], width: NFT_CARD_WIDTH, height: NFT_CARD_WIDTH, objectFit: "cover", diff --git a/src/module/sdk/NearSdkService/NearSdkService.ts b/src/module/sdk/NearSdkService/NearSdkService.ts index b31ffd766..8a41b0717 100644 --- a/src/module/sdk/NearSdkService/NearSdkService.ts +++ b/src/module/sdk/NearSdkService/NearSdkService.ts @@ -24,6 +24,7 @@ import { CreateNearSdkWithMnemonicParams, CreateNearSdkWithSecretKeyParams, Action, + NftTokenMetadata, } from "./NearSdkService.types"; import { MINIMUM_UNSTAKED, @@ -57,6 +58,8 @@ import { NFT_OWNER_TOKENS_SET_METHOD, STAKING_WITHDRAW_GAS, STAKING_WITHDRAW_ALL_GAS, + NFT_GET_TOKENS_BY_OWNER, + GET_TOKEN_METADATA_METHOD, } from "../utils/near.constants"; import { addNearAmounts, @@ -930,11 +933,31 @@ export class NearSDKService { // User has nfts of contract async getNftTokensAmount(contractId: string): Promise { const account = await this.getAccount(); - return account.viewFunction({ - contractId, - methodName: NFT_SUPPLY_METHOD, - args: { account_id: account.accountId }, - }); + try { + return await account.viewFunction({ + contractId, + methodName: NFT_SUPPLY_METHOD, + args: { account_id: account.accountId }, + }); + } catch (err: any) { + if (!err.toString().includes("Contract method is not found")) { + throw err; + } + try { + // example contract: mintv2.sharddog.near + const nftsIds = await account.viewFunction({ + contractId, + methodName: NFT_GET_TOKENS_BY_OWNER, + args: { account_id: account.accountId }, + }); + + if (Array.isArray(nftsIds)) { + return nftsIds.length; + } + } catch {} + + return 0; + } } async getNftMetadata(contractId: string): Promise { @@ -947,18 +970,34 @@ export class NearSDKService { } // Mintbase non-standard method - private async getNftTokenMetadata(contractId: string, tokenId: string, baseUri: string): Promise { + private async getNftTokenMetadata(contractId: string, tokenId: string, baseUri: string): Promise { const account = await this.getAccount(); - let metadata = await account.viewFunction({ - contractId, - methodName: NFT_TOKEN_METADATA_METHOD, - args: { token_id: tokenId }, - }); + let metadata; + + try { + metadata = await account.viewFunction({ + contractId, + methodName: NFT_TOKEN_METADATA_METHOD, + args: { token_id: tokenId }, + }); - if (!metadata.media && metadata.reference) { + if (!(metadata as NftMetadata).media && (metadata as NftMetadata).reference) { + try { + metadata = await (await fetch(`${baseUri}/${(metadata as NftMetadata).reference}`)).json(); + } catch {} + } + } catch (err: any) { + if (!err.toString().includes("Contract method is not found")) { + throw err; + } try { - metadata = await (await fetch(`${baseUri}/${metadata.reference}`)).json(); - } catch {} + // example contract: mintv2.sharddog.near + return await account.viewFunction({ + contractId, + methodName: GET_TOKEN_METADATA_METHOD, + args: { token_id: Number(tokenId) }, // We need to cast toa number here to avoid smart contract type issues + }); + } catch (e) {} } return metadata; @@ -984,6 +1023,7 @@ export class NearSDKService { } const media = token.metadata.media; + if (media && media.includes("://")) { token.metadata.media_url = media; token.metadata.media = null; @@ -994,6 +1034,22 @@ export class NearSDKService { token.metadata.media = null; } + if (!token.metadata.media_url) { + const reference = token.metadata.reference; + + if (reference) { + if (reference.includes("://")) { + token.metadata.media_url = reference; + token.metadata.media = null; + } + if (!reference.includes("://") && !reference.startsWith("data:image")) { + const url = baseUri ? `${baseUri}/${reference}` : `https://cloudflare-ipfs.com/ipfs/${reference}`; + token.metadata.media_url = url; + token.metadata.media = null; + } + } + } + return token; } @@ -1016,11 +1072,24 @@ export class NearSDKService { const account = await this.getAccount(); let tokens: NftToken[] = []; try { - const tokenIds = await account.viewFunction({ - contractId, - methodName: NFT_OWNER_TOKENS_SET_METHOD, - args: { account_id: account.accountId }, - }); + let tokenIds; + try { + tokenIds = await account.viewFunction({ + contractId, + methodName: NFT_OWNER_TOKENS_SET_METHOD, + args: { account_id: account.accountId }, + }); + } catch (err: any) { + if (!err.toString().includes("Contract method is not found")) { + throw err; + } + tokenIds = await account.viewFunction({ + contractId, + methodName: NFT_GET_TOKENS_BY_OWNER, + args: { account_id: account.accountId }, + }); + } + tokens = await Promise.all( tokenIds.map(async (tokenId: number | string) => ({ token_id: tokenId.toString(), @@ -1029,7 +1098,7 @@ export class NearSDKService { })), ); } catch (err: any) { - if (!err.toString().includes("MethodResolveError(MethodNotFound)")) { + if (!err.toString().includes("Contract method is not found")) { throw err; } tokens = await account.viewFunction({ @@ -1038,6 +1107,7 @@ export class NearSDKService { args: { account_id: account.accountId }, }); } + const parsedTokens = tokens.map((token: any) => this.parseNftToken(token, contractId, baseUri)); return Promise.all(parsedTokens); } @@ -1050,9 +1120,9 @@ export class NearSDKService { let contractNfts = 0; try { contractNfts = await this.getNftTokensAmount(contractId); - } catch { + } catch (e) { // eslint-disable-next-line no-console - console.warn("Error getting nft amount for contract", contractId); + console.warn("Error getting nft amount for contract " + contractId, e); } if (contractNfts > 0) { @@ -1062,9 +1132,9 @@ export class NearSDKService { nftTokens.push( ...newNftTokens.map((token: NftToken) => ({ ...token, collection_metadata: collectionMetadata, contractId })), ); - } catch { + } catch (e) { // eslint-disable-next-line no-console - console.warn("Error getting nft tokens for contract", contractId); + console.warn("Error getting nft tokens for contract " + contractId, e); } } } diff --git a/src/module/sdk/utils/near.constants.ts b/src/module/sdk/utils/near.constants.ts index da5626658..e3fa5fd63 100644 --- a/src/module/sdk/utils/near.constants.ts +++ b/src/module/sdk/utils/near.constants.ts @@ -24,7 +24,9 @@ export const NFT_TRANSFER_METHOD = "nft_transfer"; export const NFT_METADATA_METHOD = "nft_metadata"; export const NFT_TOKEN_METHOD = "nft_token"; export const NFT_TOKEN_METADATA_METHOD = "nft_token_metadata"; +export const GET_TOKEN_METADATA_METHOD = "get_token_metadata"; export const NFT_SUPPLY_METHOD = "nft_supply_for_owner"; +export const NFT_GET_TOKENS_BY_OWNER = "get_tokens_by_owner"; export const NFT_OWNER_TOKENS_METHOD = "nft_tokens_for_owner"; export const NFT_OWNER_TOKENS_SET_METHOD = "nft_tokens_for_owner_set"; //Fungible token From 118dcbc94c947721f44bfc652ddd908bc026b01b Mon Sep 17 00:00:00 2001 From: Jordi Parra Crespo Date: Fri, 11 Oct 2024 12:52:24 +0200 Subject: [PATCH 2/2] fix: add change in the changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b3c393d3..7c6a55aef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,3 +27,7 @@ This document logs notable, developer-facing updates to the NEAR Mobile Wallet. - Add `app version` in settings [feat/add-versions](https://github.com/Peersyst/near-mobile-wallet/pull/536) - Add actions in main app menu in [feat/main-button](https://github.com/Peersyst/near-mobile-wallet/pull/535) - Refactor explore dApps tab [refactor/explore-dapp](https://github.com/Peersyst/near-mobile-wallet/pull/533) + +### 🐛 Bug Fixes + +- Fix NFTs not being displayed in the APP [fix/nft-not-being-displayed](https://github.com/Peersyst/near-mobile-wallet/pull/537)