diff --git a/packages/mask/src/plugins/NextID/components/BindDialog.tsx b/packages/mask/src/plugins/NextID/components/BindDialog.tsx index e5e3698a0a94..4879f7f3e952 100644 --- a/packages/mask/src/plugins/NextID/components/BindDialog.tsx +++ b/packages/mask/src/plugins/NextID/components/BindDialog.tsx @@ -13,6 +13,7 @@ import { useBindPayload } from '../hooks/useBindPayload' import { usePersonaSign } from '../hooks/usePersonaSign' import { useWalletSign } from '../hooks/useWalletSign' import { NextIDProof } from '@masknet/web3-providers' +import { MaskMessages } from '../../../../shared' interface BindDialogProps { open: boolean @@ -52,6 +53,9 @@ export const BindDialog = memo(({ open, onClose, persona, onBou variant: 'success', message: t.notify_wallet_sign_request_success(), }) + + MaskMessages.events.ownProofChanged.sendToAll() + await delay(2000) onBound() onClose() diff --git a/packages/mask/src/plugins/NextID/components/Tip/TipButton.tsx b/packages/mask/src/plugins/NextID/components/Tip/TipButton.tsx index 227c540593c9..76cb68fe9bed 100644 --- a/packages/mask/src/plugins/NextID/components/Tip/TipButton.tsx +++ b/packages/mask/src/plugins/NextID/components/Tip/TipButton.tsx @@ -6,12 +6,13 @@ import { NextIDProof } from '@masknet/web3-providers' import type { TooltipProps } from '@mui/material' import classnames from 'classnames' import { uniq } from 'lodash-unified' -import { FC, HTMLProps, MouseEventHandler, useCallback, useMemo } from 'react' +import { FC, HTMLProps, MouseEventHandler, useCallback, useEffect, useMemo } from 'react' import { useAsync, useAsyncFn, useAsyncRetry } from 'react-use' import Services from '../../../../extension/service' import { activatedSocialNetworkUI } from '../../../../social-network' import { useI18N } from '../../locales' import { PluginNextIdMessages } from '../../messages' +import { MaskMessages } from '../../../../../shared' interface Props extends HTMLProps { addresses?: string[] @@ -71,7 +72,11 @@ export const TipButton: FC = ({ return Services.Identity.queryPersonaByProfile(receiver) }, [receiver]) - const { value: isAccountVerified, loading: loadingVerifyInfo } = useAsync(() => { + const { + value: isAccountVerified, + loading: loadingVerifyInfo, + retry: retryLoadVerifyInfo, + } = useAsyncRetry(() => { if (!receiverPersona?.publicHexKey || !receiver?.userId) return Promise.resolve(false) return NextIDProof.queryIsBound(receiverPersona.publicHexKey, platform, receiver.userId, true) }, [receiverPersona?.publicHexKey, platform, receiver?.userId]) @@ -91,6 +96,13 @@ export const TipButton: FC = ({ useAsync(queryBindings, [queryBindings]) + useEffect(() => { + return MaskMessages.events.ownProofChanged.on(() => { + retryLoadVerifyInfo() + queryBindings() + }) + }, []) + const allAddresses = useMemo(() => { return uniq([...(walletsState.value || []), ...addresses]) }, [walletsState.value, addresses]) diff --git a/packages/mask/src/plugins/NextID/components/UnbindDialog.tsx b/packages/mask/src/plugins/NextID/components/UnbindDialog.tsx index aadc5dc1cf72..cc0b95ba29b0 100644 --- a/packages/mask/src/plugins/NextID/components/UnbindDialog.tsx +++ b/packages/mask/src/plugins/NextID/components/UnbindDialog.tsx @@ -13,6 +13,7 @@ import { delay } from '@dimensiondev/kit' import { UnbindPanelUI } from './UnbindPanelUI' import { UnbindConfirm } from './UnbindConfirm' import { NextIDProof } from '@masknet/web3-providers' +import { MaskMessages } from '../../../../shared' interface VerifyWalletDialogProps { unbindAddress: string @@ -56,6 +57,9 @@ export const UnbindDialog = memo(({ unbindAddress, onCl variant: 'success', message: t.notify_wallet_sign_request_success(), }) + + MaskMessages.events.ownProofChanged.sendToAll() + await delay(2000) onUnBound() onClose() diff --git a/packages/web3-providers/src/NextID/helper.ts b/packages/web3-providers/src/NextID/helper.ts index 560e3c9d8363..0708e8ce7e3c 100644 --- a/packages/web3-providers/src/NextID/helper.ts +++ b/packages/web3-providers/src/NextID/helper.ts @@ -6,6 +6,10 @@ const fetchCache = new LRU({ ttl: 20000, }) +export function deleteCache(key: string) { + fetchCache.delete(key) +} + export async function fetchJSON( url: string, requestInit?: RequestInit, diff --git a/packages/web3-providers/src/NextID/proof.ts b/packages/web3-providers/src/NextID/proof.ts index 7f126278fce9..6a134c0e4d42 100644 --- a/packages/web3-providers/src/NextID/proof.ts +++ b/packages/web3-providers/src/NextID/proof.ts @@ -1,4 +1,4 @@ -import { fetchJSON } from './helper' +import { deleteCache, fetchJSON } from './helper' import urlcat from 'urlcat' import { first } from 'lodash-unified' import { @@ -32,9 +32,22 @@ interface CreatePayloadResponse { created_at: string } +const getPersonaQueryURL = (platform: string, identity: string) => + urlcat(BASE_URL, '/v1/proof', { + platform, + identity, + }) + +const geyExistedBindingQueryURL = (platform: string, identity: string, personaPublicKey: string) => + urlcat(BASE_URL, '/v1/proof/exists', { + platform, + identity, + public_key: personaPublicKey, + }) + export class NextIDProofAPI implements NextIDBaseAPI.Proof { // TODO: remove 'bind' in project for business context. - bindProof( + async bindProof( uuid: string, personaPublicKey: string, action: NextIDAction, @@ -61,18 +74,23 @@ export class NextIDProofAPI implements NextIDBaseAPI.Proof { created_at: createdAt, } - return fetchJSON(urlcat(BASE_URL, '/v1/proof'), { + const result = await fetchJSON(urlcat(BASE_URL, '/v1/proof'), { body: JSON.stringify(requestBody), method: 'POST', }) + + // Should delete cache when proof status changed + const cacheKeyOfQueryPersona = getPersonaQueryURL(NextIDPlatform.NextId, personaPublicKey) + const cacheKeyOfExistedBinding = geyExistedBindingQueryURL(platform, identity, personaPublicKey) + deleteCache(cacheKeyOfQueryPersona) + deleteCache(cacheKeyOfExistedBinding) + + return result } async queryExistedBindingByPersona(personaPublicKey: string, enableCache?: boolean) { - const response = await fetchJSON( - urlcat(BASE_URL, '/v1/proof', { platform: NextIDPlatform.NextId, identity: personaPublicKey }), - {}, - enableCache, - ) + const url = getPersonaQueryURL(NextIDPlatform.NextId, personaPublicKey) + const response = await fetchJSON(url, {}, enableCache) // Will have only one item when query by personaPublicKey return first(response.unwrap().ids) } @@ -91,15 +109,8 @@ export class NextIDProofAPI implements NextIDBaseAPI.Proof { async queryIsBound(personaPublicKey: string, platform: NextIDPlatform, identity: string, enableCache?: boolean) { if (!platform && !identity) return false - const result = await fetchJSON( - urlcat(BASE_URL, '/v1/proof/exists', { - platform: platform, - identity: identity, - public_key: personaPublicKey, - }), - {}, - enableCache, - ) + const url = geyExistedBindingQueryURL(platform, identity, personaPublicKey) + const result = await fetchJSON(url, {}, enableCache) return result.map(() => true).unwrapOr(false) }