|
@@ -2,6 +2,7 @@ import { FC, PropsWithChildren, createContext, useCallback, useContext, useEffec
|
|
|
|
|
|
import { useMemberships } from '@/api/hooks/membership'
|
|
|
import { ViewErrorFallback } from '@/components/ViewErrorFallback'
|
|
|
+import { JoystreamContext, JoystreamContextValue } from '@/providers/joystream/joystream.provider'
|
|
|
import { isMobile } from '@/utils/browser'
|
|
|
import { AssetLogger, SentryLogger } from '@/utils/logs'
|
|
|
import { retryPromise } from '@/utils/misc'
|
|
@@ -16,13 +17,22 @@ UserContext.displayName = 'UserContext'
|
|
|
const isMobileDevice = isMobile()
|
|
|
|
|
|
export const UserProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
|
- const { accountId, memberId, channelId, walletAccounts, walletStatus, lastUsedWalletName } = useUserStore(
|
|
|
- (state) => state
|
|
|
- )
|
|
|
- const { setActiveUser, setSignInModalOpen } = useUserStore((state) => state.actions)
|
|
|
+ const {
|
|
|
+ accountId,
|
|
|
+ memberId,
|
|
|
+ channelId,
|
|
|
+ walletAccounts,
|
|
|
+ walletStatus,
|
|
|
+ lastUsedWalletName,
|
|
|
+ wallet,
|
|
|
+ lastChainMetadataVersion,
|
|
|
+ } = useUserStore((state) => state)
|
|
|
+ const { setActiveUser, setSignInModalOpen, setLastChainMetadataVersion } = useUserStore((state) => state.actions)
|
|
|
const { initSignerWallet } = useSignerWallet()
|
|
|
+ const joystreamCtx = useContext<JoystreamContextValue | undefined>(JoystreamContext)
|
|
|
|
|
|
const [isAuthLoading, setIsAuthLoading] = useState(true)
|
|
|
+ const [isSignerMetadataOutdated, setIsSignerMetadataOutdated] = useState(false)
|
|
|
|
|
|
const accountsIds = walletAccounts.map((a) => a.address)
|
|
|
|
|
@@ -153,6 +163,51 @@ export const UserProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
|
const activeChannel =
|
|
|
(activeMembership && activeMembership?.channels.find((channel) => channel.id === channelId)) || null
|
|
|
|
|
|
+ const checkSignerStatus = useCallback(async () => {
|
|
|
+ const chainMetadata = await joystreamCtx?.joystream?.getChainMetadata()
|
|
|
+
|
|
|
+ if (wallet?.extension.metadata && chainMetadata) {
|
|
|
+ const [localGenesisHash, localSpecVersion] = lastChainMetadataVersion ?? ['', 0]
|
|
|
+
|
|
|
+ // update was skipped
|
|
|
+ if (localGenesisHash === chainMetadata.genesisHash && localSpecVersion === chainMetadata.specVersion) {
|
|
|
+ return setIsSignerMetadataOutdated(false)
|
|
|
+ }
|
|
|
+
|
|
|
+ const extensionMetadata = await wallet.extension.metadata.get()
|
|
|
+ const currentChain = extensionMetadata.find(
|
|
|
+ (infoEntry: { specVersion: number; genesisHash: string }) =>
|
|
|
+ infoEntry.genesisHash === chainMetadata?.genesisHash
|
|
|
+ )
|
|
|
+
|
|
|
+ // if there isn't even a metadata entry for node with specific genesis hash then update
|
|
|
+ if (!currentChain) {
|
|
|
+ return setIsSignerMetadataOutdated(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ // if there is metadata for this node then verify specVersion
|
|
|
+ const isOutdated = currentChain.specVersion < chainMetadata.specVersion
|
|
|
+ setIsSignerMetadataOutdated(isOutdated)
|
|
|
+ }
|
|
|
+ }, [joystreamCtx?.joystream, lastChainMetadataVersion, wallet?.extension.metadata])
|
|
|
+
|
|
|
+ const updateSignerMetadata = useCallback(async () => {
|
|
|
+ const chainMetadata = await joystreamCtx?.joystream?.getChainMetadata()
|
|
|
+ return wallet?.extension.metadata.provide(chainMetadata)
|
|
|
+ }, [joystreamCtx?.joystream, wallet?.extension.metadata])
|
|
|
+
|
|
|
+ const skipSignerMetadataUpdate = useCallback(async () => {
|
|
|
+ const chainMetadata = await joystreamCtx?.joystream?.getChainMetadata()
|
|
|
+ if (chainMetadata) {
|
|
|
+ setLastChainMetadataVersion(chainMetadata.genesisHash, chainMetadata.specVersion)
|
|
|
+ setIsSignerMetadataOutdated(false)
|
|
|
+ }
|
|
|
+ }, [joystreamCtx?.joystream, setLastChainMetadataVersion])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ checkSignerStatus()
|
|
|
+ }, [checkSignerStatus])
|
|
|
+
|
|
|
const isChannelBelongsToTheUserOrExists = activeMembership?.channels.length
|
|
|
? activeMembership.channels.some((channel) => channel.id === channelId)
|
|
|
: true
|
|
@@ -172,8 +227,21 @@ export const UserProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
|
isAuthLoading,
|
|
|
signIn,
|
|
|
refetchUserMemberships,
|
|
|
+ isSignerMetadataOutdated,
|
|
|
+ updateSignerMetadata,
|
|
|
+ skipSignerMetadataUpdate,
|
|
|
}),
|
|
|
- [memberships, membershipsLoading, activeMembership, activeChannel, isAuthLoading, signIn, refetchUserMemberships]
|
|
|
+ [
|
|
|
+ memberships,
|
|
|
+ membershipsLoading,
|
|
|
+ activeMembership,
|
|
|
+ isAuthLoading,
|
|
|
+ signIn,
|
|
|
+ refetchUserMemberships,
|
|
|
+ isSignerMetadataOutdated,
|
|
|
+ updateSignerMetadata,
|
|
|
+ skipSignerMetadataUpdate,
|
|
|
+ ]
|
|
|
)
|
|
|
|
|
|
if (error) {
|