From e7216d02d35ad666360ff153da7e09a409de6bb2 Mon Sep 17 00:00:00 2001 From: Lantt Date: Wed, 15 Jun 2022 15:56:49 +0800 Subject: [PATCH 1/2] fix: should check nft from chain when add custom nft in avatar --- packages/mask/shared-ui/locales/en-US.json | 1 + .../Avatar/Application/NFTListDialog.tsx | 2 +- .../src/plugins/Avatar/SNSAdaptor/AddNFT.tsx | 75 ++++++++++++++----- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json index 204889271277..41ba082b3a94 100644 --- a/packages/mask/shared-ui/locales/en-US.json +++ b/packages/mask/shared-ui/locales/en-US.json @@ -1022,6 +1022,7 @@ "nft_owner_hint": "The contract address is incorrect or the collection does not belong to you", "nft_add_dialog_title": "Add Collectible", "nft_add_button_label": "Add", + "nft_add_button_label_checking": "Checking", "nft_list_title": "NFT Avatar Setting", "nft_wallet_change": "Change", "nft_button_add_collectible": "Add Collectible", diff --git a/packages/mask/src/plugins/Avatar/Application/NFTListDialog.tsx b/packages/mask/src/plugins/Avatar/Application/NFTListDialog.tsx index 86428ec9f627..5b31770d4bdf 100644 --- a/packages/mask/src/plugins/Avatar/Application/NFTListDialog.tsx +++ b/packages/mask/src/plugins/Avatar/Application/NFTListDialog.tsx @@ -233,7 +233,7 @@ export function NFTListDialog(props: NFTListDialogProps) { ) const tokensInList = uniqBy( - [...tokens, ...collectibles], + [...tokens.filter((x) => x.chainId === chainId), ...collectibles], selectedPluginId === NetworkPluginID.PLUGIN_SOLANA ? (x) => x.tokenId : (x) => x.contract?.address.toLowerCase() + x.tokenId, diff --git a/packages/mask/src/plugins/Avatar/SNSAdaptor/AddNFT.tsx b/packages/mask/src/plugins/Avatar/SNSAdaptor/AddNFT.tsx index 18dbab877adf..2cbfea3f9c26 100644 --- a/packages/mask/src/plugins/Avatar/SNSAdaptor/AddNFT.tsx +++ b/packages/mask/src/plugins/Avatar/SNSAdaptor/AddNFT.tsx @@ -4,8 +4,14 @@ import { Button, DialogContent, InputBase, Typography } from '@mui/material' import { useCallback, useState } from 'react' import { InjectedDialog } from '@masknet/shared' import { useI18N } from '../../../utils' -import { useAccount, useChainId, useCurrentWeb3NetworkPluginID, useWeb3Hub } from '@masknet/plugin-infra/web3' -import { isSameAddress, NetworkPluginID } from '@masknet/web3-shared-base' +import { + useAccount, + useChainId, + useCurrentWeb3NetworkPluginID, + useWeb3Connection, + useWeb3Hub, +} from '@masknet/plugin-infra/web3' +import type { NetworkPluginID } from '@masknet/web3-shared-base' import type { AllChainsNonFungibleToken } from '../types' const useStyles = makeStyles()((theme) => ({ @@ -50,10 +56,12 @@ export function AddNFT(props: AddNFTProps) { const [address, setAddress] = useState('') const [tokenId, setTokenId] = useState('') const [message, setMessage] = useState('') + const [checking, toggleChecking] = useState(false) const currentPluginId = useCurrentWeb3NetworkPluginID(expectedPluginID) const _account = useAccount(expectedPluginID, account) const currentChainId = useChainId(expectedPluginID, chainId) const hub = useWeb3Hub(currentPluginId, { chainId: currentChainId, account: _account }) + const connection = useWeb3Connection(currentPluginId) const onClick = useCallback(async () => { if (!address) { @@ -69,23 +77,49 @@ export function AddNFT(props: AddNFTProps) { return } - const token = await hub.getNonFungibleAsset(address, tokenId, { chainId: currentChainId }) - if (!token) { - setMessage(t('plugin_avatar_asset')) - return - } + toggleChecking(true) + let tokenDetailed - if (token.contract?.chainId && token.contract?.chainId !== currentChainId) { - setMessage(t('plugin_avatar_chain_error')) - return - } - if (!token || !isSameAddress(token.owner?.address ?? token?.ownerId, _account)) { - setMessage(t('nft_owner_hint')) + try { + const asset = await hub.getNonFungibleAsset(address, tokenId, { chainId: currentChainId }) + + const token = await connection?.getNonFungibleToken(address ?? '', tokenId, undefined, { + chainId: currentChainId, + }) + + tokenDetailed = { ...(token ?? {}), ...(asset ?? {}) } + + if (!tokenDetailed) { + setMessage(t('plugin_avatar_asset')) + toggleChecking(false) + return + } + + if (tokenDetailed?.contract?.chainId && tokenDetailed?.contract?.chainId !== currentChainId) { + setMessage(t('plugin_avatar_chain_error')) + toggleChecking(false) + return + } + + const isOwner = await connection?.getNonFungibleTokenOwnership(address, _account, tokenId, undefined, { + chainId: currentChainId, + }) + + if (!isOwner) { + setMessage(t('nft_owner_hint')) + toggleChecking(false) + return + } + + onAddClick?.(tokenDetailed as AllChainsNonFungibleToken) + toggleChecking(false) + handleClose() + } catch { + setMessage(t('plugin_avatar_asset')) + toggleChecking(false) return } - onAddClick?.(token) - handleClose() - }, [tokenId, address, onAddClick, onClose, currentChainId, hub, _account]) + }, [tokenId, address, onAddClick, onClose, currentChainId, hub, _account, connection]) const onAddressChange = useCallback((address: string) => { setMessage('') @@ -108,8 +142,13 @@ export function AddNFT(props: AddNFTProps) { onClose={handleClose} titleBarIconStyle="close"> -
Date: Wed, 15 Jun 2022 17:19:28 +0800 Subject: [PATCH 2/2] feat: add cache for next id query request --- packages/web3-providers/src/NextID/kv.ts | 10 ++++++++-- packages/web3-providers/src/NextID/proof.ts | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/web3-providers/src/NextID/kv.ts b/packages/web3-providers/src/NextID/kv.ts index 2a4fd3dc4f74..c83e7ac98e4b 100644 --- a/packages/web3-providers/src/NextID/kv.ts +++ b/packages/web3-providers/src/NextID/kv.ts @@ -3,7 +3,7 @@ */ import urlcat from 'urlcat' import type { NextIDStoragePayload, NextIDPlatform } from '@masknet/shared-base' -import { fetchJSON } from './helper' +import { deleteCache, fetchJSON } from './helper' import { Err, Ok, Result } from 'ts-results' import type { NextIDBaseAPI } from '../types' import { KV_BASE_URL_DEV, KV_BASE_URL_PROD } from './constants' @@ -44,7 +44,11 @@ export class NextIDStorageAPI implements NextIDBaseAPI.Storage { persona: string proofs: Proof[] } - const response = await fetchJSON(urlcat(BASE_URL, '/v1/kv', { persona: personaPublicKey })) + const response = await fetchJSON( + urlcat(BASE_URL, '/v1/kv', { persona: personaPublicKey }), + undefined, + true, + ) if (!response.ok) return Err('User not found') const proofs = (response.val.proofs ?? []) .filter((x) => x.platform === platform) @@ -124,6 +128,8 @@ export class NextIDStorageAPI implements NextIDBaseAPI.Storage { created_at: createdAt, } + deleteCache(urlcat(BASE_URL, '/v1/kv', { persona: personaPublicKey })) + return fetchJSON(urlcat(BASE_URL, '/v1/kv'), { body: JSON.stringify(requestBody), method: 'POST', diff --git a/packages/web3-providers/src/NextID/proof.ts b/packages/web3-providers/src/NextID/proof.ts index af86f21422b3..3a10c9ef22de 100644 --- a/packages/web3-providers/src/NextID/proof.ts +++ b/packages/web3-providers/src/NextID/proof.ts @@ -81,8 +81,10 @@ export class NextIDProofAPI implements NextIDBaseAPI.Proof { // Should delete cache when proof status changed const cacheKeyOfQueryPersona = getPersonaQueryURL(NextIDPlatform.NextID, personaPublicKey) + const cacheKeyOfQueryPlatform = getPersonaQueryURL(platform, identity) const cacheKeyOfExistedBinding = getExistedBindingQueryURL(platform, identity, personaPublicKey) deleteCache(cacheKeyOfQueryPersona) + deleteCache(cacheKeyOfQueryPlatform) deleteCache(cacheKeyOfExistedBinding) return result @@ -98,7 +100,11 @@ export class NextIDProofAPI implements NextIDBaseAPI.Proof { async queryExistedBindingByPlatform(platform: NextIDPlatform, identity: string, page?: number) { if (!platform && !identity) return [] - const response = await fetchJSON(urlcat(BASE_URL, '/v1/proof', { platform, identity })) + const response = await fetchJSON( + urlcat(BASE_URL, '/v1/proof', { platform, identity }), + undefined, + true, + ) // TODO: merge Pagination into this return response.unwrap().ids