diff --git a/apps/web/src/components/App/App.tsx b/apps/web/src/components/App/App.tsx
index 160c292d2a..603113a556 100644
--- a/apps/web/src/components/App/App.tsx
+++ b/apps/web/src/components/App/App.tsx
@@ -1,20 +1,25 @@
-import { useCurrentAccount } from "@umami/state";
+import { useHandleSession } from "@umami/state";
import { Layout } from "../../Layout";
+import { SessionLogin } from "../../views/SessionLogin/SessionLogin";
import { Welcome } from "../../views/Welcome";
import { BeaconProvider } from "../beacon";
import { WalletConnectProvider } from "../WalletConnect/WalletConnectProvider";
export const App = () => {
- const currentAccount = useCurrentAccount();
+ const { isSessionActive, isOnboarded } = useHandleSession();
- return currentAccount ? (
-
-
-
-
-
- ) : (
-
- );
+ if (!isOnboarded()) {
+ return ;
+ } else if (!isSessionActive) {
+ return ;
+ } else {
+ return (
+
+
+
+
+
+ );
+ }
};
diff --git a/apps/web/src/components/Onboarding/SetupPassword/SetupPassword.tsx b/apps/web/src/components/Onboarding/SetupPassword/SetupPassword.tsx
index 0a4059877e..c273bbe3f6 100644
--- a/apps/web/src/components/Onboarding/SetupPassword/SetupPassword.tsx
+++ b/apps/web/src/components/Onboarding/SetupPassword/SetupPassword.tsx
@@ -11,7 +11,7 @@ import {
Text,
} from "@chakra-ui/react";
import { useMultiForm } from "@umami/components";
-import { useIsPasswordSet, useSessionTimeout } from "@umami/state";
+import { useHandleSession, useIsPasswordSet } from "@umami/state";
import { defaultDerivationPathTemplate } from "@umami/tezos";
import { FormProvider } from "react-hook-form";
@@ -72,7 +72,7 @@ export const SetupPassword = ({ mode }: SetupPasswordProps) => {
const color = useColor();
const { onSubmit, isLoading } = useGetSetupPasswordSubmitHandler(mode);
const isPasswordSet = useIsPasswordSet();
- const { setupSessionTimeout } = useSessionTimeout();
+ const { setupSessionTimeout } = useHandleSession();
const form = useMultiForm({
mode: "all",
diff --git a/apps/web/src/providers/ReduxStore.tsx b/apps/web/src/providers/ReduxStore.tsx
index f32546b63c..ea43a790a6 100644
--- a/apps/web/src/providers/ReduxStore.tsx
+++ b/apps/web/src/providers/ReduxStore.tsx
@@ -14,12 +14,14 @@ export const ReduxStore = ({ children }: PropsWithChildren) => (
const ReduxStoreContent = ({ children }: PropsWithChildren) => {
const nonce = getOrCreateUserNonce();
+
if (!nonce) {
return <>{children}>;
}
if (!persistor) {
const { persistor } = initializePersistence(store, nonce);
setupPersistor(persistor);
+
return (
{children}
diff --git a/apps/web/src/views/SessionLogin/SessionLogin.tsx b/apps/web/src/views/SessionLogin/SessionLogin.tsx
new file mode 100644
index 0000000000..36e6d18f44
--- /dev/null
+++ b/apps/web/src/views/SessionLogin/SessionLogin.tsx
@@ -0,0 +1,67 @@
+import { Button, Center, Flex, type FlexProps, Heading, Icon, Text } from "@chakra-ui/react";
+import { type FieldValues, FormProvider, useForm } from "react-hook-form";
+
+import { LogoLightIcon, TezosLogoIcon } from "../../assets/icons";
+import { PasswordInput } from "../../components/PasswordInput";
+import { useColor } from "../../styles/useColor";
+
+export const SessionLogin = () => {
+ const color = useColor();
+
+ const form = useForm({
+ defaultValues: {
+ password: "",
+ },
+ mode: "onBlur",
+ });
+
+ const onSubmit = (data: FieldValues) => {
+ console.log(data);
+ };
+
+ return (
+
+
+
+
+
+
+ Welcome back!
+
+
+ You need to sign back in to use your wallet.
+
+
+
+
+
+
+
+
+ );
+};
+
+const Logo = (props: FlexProps) => (
+
+
+ Powered by
+
+
+
+);
diff --git a/apps/web/src/views/SessionLogin/index.ts b/apps/web/src/views/SessionLogin/index.ts
new file mode 100644
index 0000000000..b4e2067041
--- /dev/null
+++ b/apps/web/src/views/SessionLogin/index.ts
@@ -0,0 +1 @@
+export * from "./SessionLogin";
diff --git a/packages/state/src/hooks/session.ts b/packages/state/src/hooks/session.ts
index e3029071c9..f228c0027b 100644
--- a/packages/state/src/hooks/session.ts
+++ b/packages/state/src/hooks/session.ts
@@ -1,10 +1,19 @@
+import { useAppDispatch } from "./useAppDispatch";
+import { useAppSelector } from "./useAppSelector";
+import { setHasSession } from "../slices/session";
+
const SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes from login
-export const useSessionTimeout = () => {
+export const useHandleSession = () => {
+ const isOnboarded = () => !!localStorage.getItem("user_requirements_nonce");
+ const isSessionActive = useAppSelector(state => state.session.hasSession);
+ const dispatch = useAppDispatch();
+
const setupSessionTimeout = () => {
try {
- const timeoutId = window.setTimeout(() => {
+ const timeoutId = setTimeout(() => {
sessionStorage.clear();
+ dispatch(setHasSession(false));
}, SESSION_TIMEOUT);
// Store timeout ID in case we need to clear it
@@ -14,5 +23,5 @@ export const useSessionTimeout = () => {
}
};
- return { setupSessionTimeout };
+ return { setupSessionTimeout, isSessionActive, isOnboarded };
};
diff --git a/packages/state/src/reducer.ts b/packages/state/src/reducer.ts
index ca6f68fc45..a19a22764d 100644
--- a/packages/state/src/reducer.ts
+++ b/packages/state/src/reducer.ts
@@ -16,6 +16,7 @@ import { errorsSlice } from "./slices/errors";
import { multisigsSlice } from "./slices/multisigs";
import { networksSlice } from "./slices/networks";
import { protocolSettingsSlice } from "./slices/protocolSettings";
+import { sessionSlice } from "./slices/session";
import { tokensSlice } from "./slices/tokens";
let TEST_STORAGE: Storage | undefined;
@@ -47,6 +48,7 @@ export const makeReducer = () => {
networks: networksSlice.reducer,
protocolSettings: protocolSettingsSlice.reducer,
tokens: tokensSlice.reducer,
+ session: sessionSlice.reducer,
});
return (state: any, action: Action) => {
@@ -68,7 +70,7 @@ export const makePersistConfigs = (storage_: Storage | undefined, password?: str
key: "root",
version: VERSION,
storage,
- blacklist: ["accounts", "assets", "announcement", "tokens", "protocolSettings"],
+ blacklist: ["accounts", "assets", "announcement", "tokens", "protocolSettings", "session"],
migrate: createAsyncMigrate(mainStoreMigrations, { debug: false }),
transforms: [
encryptTransform(
diff --git a/packages/state/src/slices/session.ts b/packages/state/src/slices/session.ts
new file mode 100644
index 0000000000..05e4bc14e0
--- /dev/null
+++ b/packages/state/src/slices/session.ts
@@ -0,0 +1,15 @@
+import { createSlice } from "@reduxjs/toolkit";
+
+export const sessionSlice = createSlice({
+ name: "session",
+ initialState: {
+ hasSession: false,
+ },
+ reducers: {
+ setHasSession: (state, action) => {
+ state.hasSession = action.payload;
+ },
+ },
+});
+
+export const { setHasSession } = sessionSlice.actions;
diff --git a/packages/state/src/store.ts b/packages/state/src/store.ts
index a8da7f9149..949e894e97 100644
--- a/packages/state/src/store.ts
+++ b/packages/state/src/store.ts
@@ -3,6 +3,7 @@ import { type Storage, persistReducer, persistStore } from "redux-persist";
import { makePersistConfigs, makeReducer } from "./reducer";
import { accountsSlice } from "./slices/accounts/accounts";
+import { setHasSession } from "./slices/session";
// Create initial store without persistence
export const makeStore = () => {
@@ -55,6 +56,7 @@ export const initializePersistence = (
// Update store's reducer
store.replaceReducer(finalReducer);
+ store.dispatch(setHasSession(true));
const persistor = persistStore(store);
return { persistor };