From 16c5508cb4b4897aa601ef34a6428a850eac9681 Mon Sep 17 00:00:00 2001 From: Jose Felix Date: Sun, 5 Jan 2025 15:29:24 -0400 Subject: [PATCH] feat: handle wallet deletion --- packages/mobile/app/_layout.tsx | 65 +++++++++++++++++++ packages/mobile/hooks/use-wallets.ts | 35 +--------- .../mobile-sessions/create-mobile-session.tsx | 2 + packages/web/modals/profile/index.tsx | 1 + 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/packages/mobile/app/_layout.tsx b/packages/mobile/app/_layout.tsx index 1ffe0c5492..7aa3c80da8 100644 --- a/packages/mobile/app/_layout.tsx +++ b/packages/mobile/app/_layout.tsx @@ -4,6 +4,7 @@ import { localLink, makeSkipBatchLink } from "@osmosis-labs/trpc"; import { constructEdgeRouterKey, constructEdgeUrlPathname, + isNil, } from "@osmosis-labs/utils"; import { ThemeProvider } from "@react-navigation/native"; import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; @@ -15,12 +16,15 @@ import { Redirect, Stack } from "expo-router"; import * as SplashScreen from "expo-splash-screen"; import { StatusBar } from "expo-status-bar"; import { useEffect, useState } from "react"; +import { Alert } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Toaster } from "sonner-native"; import { LockScreenModal } from "~/components/lock-screen-modal"; import { DefaultTheme } from "~/constants/themes"; import { useWallets } from "~/hooks/use-wallets"; +import { useCurrentWalletStore } from "~/stores/current-wallet"; +import { useKeyringStore } from "~/stores/keyring"; import { getMobileAssetListAndChains } from "~/utils/asset-lists"; import { mmkvStorage } from "~/utils/mmkv"; import { api, RouterKeys } from "~/utils/trpc"; @@ -204,7 +208,68 @@ export default function RootLayout() { } const OnboardingObserver = () => { + const [signedOut, setSignedOut] = useState(false); const { currentWallet, wallets } = useWallets(); + const currentWalletIndex = useCurrentWalletStore( + (state) => state.currentSelectedWalletIndex + ); + + const enabled = wallets.length > 0 && currentWallet?.type === "smart-account"; + + const { + data: sessionAuthenticator, + isError: isSessionAuthenticatorError, + error: sessionAuthenticatorError, + } = api.local.oneClickTrading.getSessionAuthenticator.useQuery( + { + publicKey: + currentWallet?.type === "smart-account" ? currentWallet!.publicKey : "", + userOsmoAddress: currentWallet?.address ?? "", + }, + { + enabled, + refetchInterval: 1000 * 60 * 5, + retry: (count, error) => { + if (count > 3) { + return false; + } + if (!error?.message?.toLowerCase().match(/session not found/i)) { + return true; + } + return false; + }, + } + ); + + console.log(sessionAuthenticatorError); + + useEffect(() => { + const handleSessionError = async () => { + if ( + !signedOut && + isSessionAuthenticatorError && + sessionAuthenticatorError.message + .toLowerCase() + .match(/session not found/i) && + !isNil(currentWalletIndex) + ) { + setSignedOut(true); + Alert.alert( + "Session Deleted", + "Your wallet session was removed. Please reconnect your wallet or connect a new one.", + [{ text: "OK" }] + ); + await useKeyringStore.getState().deleteKey(currentWalletIndex); + setSignedOut(false); + } + }; + handleSessionError(); + }, [ + isSessionAuthenticatorError, + sessionAuthenticator, + currentWalletIndex, + signedOut, + ]); if (!currentWallet && wallets.length === 0) { return ; diff --git a/packages/mobile/hooks/use-wallets.ts b/packages/mobile/hooks/use-wallets.ts index c6be909c6e..593497fcb2 100644 --- a/packages/mobile/hooks/use-wallets.ts +++ b/packages/mobile/hooks/use-wallets.ts @@ -1,10 +1,8 @@ import { isNil } from "@osmosis-labs/utils"; -import { useEffect, useLayoutEffect, useMemo } from "react"; -import { Alert } from "react-native"; +import { useLayoutEffect, useMemo } from "react"; import { useCurrentWalletStore } from "~/stores/current-wallet"; import { KeyInfo, useKeyringStore } from "~/stores/keyring"; -import { api } from "~/utils/trpc"; export const useWallets = () => { const wallets = useKeyringStore((state) => state.keys); @@ -28,43 +26,12 @@ export const useWallets = () => { return wallets[currentWalletIndex]; }, [wallets, currentWalletIndex]); - const enabled = wallets.length > 0 && currentWallet?.type === "smart-account"; - - const { data: sessionAuthenticator, isError: isSessionAuthenticatorError } = - api.local.oneClickTrading.getSessionAuthenticator.useQuery( - { - publicKey: - currentWallet?.type === "smart-account" - ? currentWallet!.publicKey - : "", - userOsmoAddress: currentWallet?.address ?? "", - }, - { - enabled, - } - ); - useLayoutEffect(() => { if (wallets.length > 0 && !currentWalletIndex) { setCurrentWalletIndex(0); } }, [wallets, currentWalletIndex, setCurrentWalletIndex]); - useEffect(() => { - if ( - isSessionAuthenticatorError && - !sessionAuthenticator && - !isNil(currentWalletIndex) - ) { - Alert.alert( - "Session Deleted", - "Your wallet session was removed. Please reconnect your wallet or connect a new one.", - [{ text: "OK" }] - ); - useKeyringStore.getState().deleteKey(currentWalletIndex); - } - }, [isSessionAuthenticatorError, sessionAuthenticator, currentWalletIndex]); - return { wallets, currentWallet, diff --git a/packages/web/components/mobile-sessions/create-mobile-session.tsx b/packages/web/components/mobile-sessions/create-mobile-session.tsx index 90f46cebeb..9a0c141f03 100644 --- a/packages/web/components/mobile-sessions/create-mobile-session.tsx +++ b/packages/web/components/mobile-sessions/create-mobile-session.tsx @@ -38,6 +38,7 @@ export function CreateMobileSession() { const createOfferMutation = api.edge.webRTC.createOffer.useMutation(); const postCandidateMutation = api.edge.webRTC.postCandidate.useMutation(); const createMobileSessionMutation = useCreateMobileSession(); + const apiUtils = api.useUtils(); // Poll for the answer const fetchAnswerQuery = api.edge.webRTC.fetchAnswer.useQuery( @@ -89,6 +90,7 @@ export function CreateMobileSession() { version: 1, }) ); + apiUtils.local.oneClickTrading.getAuthenticators.invalidate(); setVerificationState((prev) => ({ ...prev, verified: true })); } catch (error) { pc.dataChannel.send( diff --git a/packages/web/modals/profile/index.tsx b/packages/web/modals/profile/index.tsx index 44e034f074..667d3908bd 100644 --- a/packages/web/modals/profile/index.tsx +++ b/packages/web/modals/profile/index.tsx @@ -145,6 +145,7 @@ export const ProfileModal: FunctionComponent< }} onAfterClose={() => { setShow1CTSettings(false); + setIsMobileSessionOpen(false); }} className="relative max-h-screen overflow-hidden sm:mx-0" >