From ad1cc0a386353c3992aec1148707663f34c3672e Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Sat, 31 Jan 2026 16:27:13 -0500 Subject: [PATCH 01/15] feat: implement onboarding guard and enhance authentication flow --- .../src/components/auth/AuthPage/AuthPage.tsx | 16 +++++++- .../OnboardingContainer.spec.tsx | 2 +- .../OnboardingContainer.tsx | 2 +- .../OnboardingGuard/OnboardingGuard.tsx | 38 +++++++++++++++++++ .../components/onboarding/OnboardingPage.tsx | 4 +- apps/deploy-web/src/hooks/useManagedWallet.ts | 6 +-- apps/deploy-web/src/pages/_app.tsx | 5 ++- apps/deploy-web/src/pages/login/index.tsx | 7 ++++ 8 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 apps/deploy-web/src/components/onboarding/OnboardingGuard/OnboardingGuard.tsx diff --git a/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx b/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx index 68e14d1962..8e44c907c0 100644 --- a/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx +++ b/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx @@ -1,6 +1,6 @@ "use client"; -import { useCallback, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { Button, Separator, Tabs, TabsContent, TabsList, TabsTrigger } from "@akashnetwork/ui/components"; import { useMutation } from "@tanstack/react-query"; import { DollarSignIcon, RocketIcon, Undo2, ZapIcon } from "lucide-react"; @@ -16,6 +16,7 @@ import { useServices } from "@src/context/ServicesProvider"; import { useWallet as useWalletOriginal } from "@src/context/WalletProvider"; import { useReturnTo } from "@src/hooks/useReturnTo"; import { useUser } from "@src/hooks/useUser"; +import { UrlService } from "@src/utils/urlUtils"; import { AuthLayout } from "../AuthLayout/AuthLayout"; import { ForgotPasswordForm } from "../ForgotPasswordForm/ForgotPasswordForm"; import type { SignInFormValues } from "../SignInForm/SignInForm"; @@ -91,9 +92,14 @@ export function AuthPage({ dependencies: d = DEPENDENCIES }: Props = {}) { }); const activeView = searchParams.get("tab") || "login"; + const isFromSignup = searchParams.has("fromSignup"); const setActiveView = useCallback( (value: string) => { - const tabId = value !== "login" && value !== "signup" && value !== "forgot-password" ? "login" : value; + if (value === "signup") { + router.push(UrlService.onboarding({ returnTo: "/" })); + return; + } + const tabId = value !== "login" && value !== "forgot-password" ? "login" : value; const newSearchParams = new URLSearchParams(searchParams); newSearchParams.set("tab", tabId); resetMutations(); @@ -102,6 +108,12 @@ export function AuthPage({ dependencies: d = DEPENDENCIES }: Props = {}) { [searchParams, router] ); + useEffect(() => { + if (activeView === "signup" && !isFromSignup) { + router.replace(UrlService.onboarding({ returnTo: "/" })); + } + }, [activeView, isFromSignup, router]); + const forgotPassword = useMutation({ async mutationFn(input: { email: string }) { if (!turnstileRef.current) { diff --git a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx index a5f77311b5..d008d5a681 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx @@ -79,7 +79,7 @@ describe("OnboardingContainer", () => { category: "onboarding" }); expect(mockUrlService.newSignup).toHaveBeenCalledWith({ fromSignup: "true" }); - expect(mockRouter.push).toHaveBeenCalledWith("/login?tab=signup"); + expect(mockRouter.push).toHaveBeenCalledWith("/login?tab=signup&fromSignup=true"); }); it("should track analytics when payment method is completed", async () => { diff --git a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx index 325822ef80..0851d5337c 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx @@ -175,7 +175,7 @@ export const OnboardingContainer: React.FunctionComponent = ({ children }) => { + const { user, isLoading: isUserLoading } = useUser(); + const { hasManagedWallet, isWalletConnected, isWalletLoading } = useWallet(); + const router = useRouter(); + const [isRedirecting, setIsRedirecting] = useState(false); + + const isExcluded = EXCLUDED_PREFIXES.some(prefix => router.pathname.startsWith(prefix)); + + useEffect(() => { + if (isUserLoading || isWalletLoading || isExcluded) { + return; + } + + if (user?.userId && !hasManagedWallet && !isWalletConnected) { + setIsRedirecting(true); + router.replace(UrlService.onboarding({ returnTo: router.asPath })); + } + }, [isUserLoading, isWalletLoading, isExcluded, user?.userId, hasManagedWallet, isWalletConnected, router]); + + if (isRedirecting) { + return ; + } + + return <>{children}; +}; diff --git a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx index 6bff1b126e..058df66195 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx @@ -6,6 +6,7 @@ import Link from "next/link"; import { CustomNextSeo } from "@src/components/shared/CustomNextSeo"; import { useServices } from "@src/context/ServicesProvider"; +import { useWallet } from "@src/context/WalletProvider"; import { useReturnTo } from "@src/hooks/useReturnTo"; import { domainName, UrlService } from "@src/utils/urlUtils"; import { OnboardingContainer } from "./OnboardingContainer/OnboardingContainer"; @@ -14,6 +15,7 @@ import { OnboardingView } from "./OnboardingView/OnboardingView"; export const OnboardingPage: FC = () => { const { analyticsService } = useServices(); const { isDeploymentReturnTo } = useReturnTo(); + const { hasManagedWallet, isWalletConnected } = useWallet(); const handleBackToConsole = () => { analyticsService.track("onboarding_back_to_console", { @@ -27,7 +29,7 @@ export const OnboardingPage: FC = () => {
{props => } - {!isDeploymentReturnTo && ( + {!isDeploymentReturnTo && (hasManagedWallet || isWalletConnected) && (
diff --git a/apps/deploy-web/src/hooks/useManagedWallet.ts b/apps/deploy-web/src/hooks/useManagedWallet.ts index 440b374728..3e7f3c3813 100644 --- a/apps/deploy-web/src/hooks/useManagedWallet.ts +++ b/apps/deploy-web/src/hooks/useManagedWallet.ts @@ -2,7 +2,6 @@ import { useEffect, useMemo } from "react"; import type { ApiManagedWalletOutput } from "@akashnetwork/http-sdk"; import { useAtom } from "jotai"; -import { useSelectedChain } from "@src/context/CustomChainProvider"; import { useUser } from "@src/hooks/useUser"; import { useCreateManagedWalletMutation, useManagedWalletQuery } from "@src/queries/useManagedWalletQuery"; import walletStore from "@src/store/walletStore"; @@ -12,7 +11,6 @@ import { useCustomUser } from "./useCustomUser"; export const useManagedWallet = () => { const { user } = useUser(); const { user: signedInUser } = useCustomUser(); - const userWallet = useSelectedChain(); const [selectedWalletType, setSelectedWalletType] = useAtom(walletStore.selectedWalletType); const { data: queried, isLoading: isInitialLoading, isFetching, refetch } = useManagedWalletQuery(user?.id); const { mutate: create, data: created, isPending: isCreating, isSuccess: isCreated, error: createError } = useCreateManagedWalletMutation(); @@ -22,10 +20,10 @@ export const useManagedWallet = () => { const selected = getSelectedStorageWallet(); useEffect(() => { - if (selectedWalletType === "custodial" && queried && !userWallet.isWalletConnected && !userWallet.isWalletConnecting) { + if (selectedWalletType === "custodial" && queried) { setSelectedWalletType("managed"); } - }, [queried, selectedWalletType, setSelectedWalletType, userWallet.isWalletConnected, userWallet.isWalletConnecting]); + }, [queried, selectedWalletType, setSelectedWalletType]); useEffect(() => { if (signedInUser?.id && (!!queried || !!created)) { diff --git a/apps/deploy-web/src/pages/_app.tsx b/apps/deploy-web/src/pages/_app.tsx index cb4bf9cbbd..87624e1f3b 100644 --- a/apps/deploy-web/src/pages/_app.tsx +++ b/apps/deploy-web/src/pages/_app.tsx @@ -20,6 +20,7 @@ import NProgress from "nprogress"; import GoogleAnalytics from "@src/components/layout/CustomGoogleAnalytics"; import { CustomIntlProvider } from "@src/components/layout/CustomIntlProvider"; import { PageHead } from "@src/components/layout/PageHead"; +import { OnboardingGuard } from "@src/components/onboarding/OnboardingGuard/OnboardingGuard"; import { UserProviders } from "@src/components/user/UserProviders/UserProviders"; import { CertificateProvider } from "@src/context/CertificateProvider"; import { CustomChainProvider } from "@src/context/CustomChainProvider"; @@ -60,7 +61,9 @@ const App: React.FunctionComponent = props => { - + + + diff --git a/apps/deploy-web/src/pages/login/index.tsx b/apps/deploy-web/src/pages/login/index.tsx index 87e10c9138..2d12a6d4e3 100644 --- a/apps/deploy-web/src/pages/login/index.tsx +++ b/apps/deploy-web/src/pages/login/index.tsx @@ -21,6 +21,7 @@ export default () => { const destination = getAuthRedirectDestination({ currentLocation: windowLocation.href, tab: searchParams.get("tab"), + fromSignup: searchParams.has("fromSignup"), services: { urlService, urlReturnToStack } }); windowLocation.assign(destination); @@ -57,6 +58,7 @@ export const getServerSideProps = defineServerSideProps({ const destination = getAuthRedirectDestination({ currentLocation: ctx.resolvedUrl, tab: ctx.query.tab, + fromSignup: ctx.resolvedUrl.includes("fromSignup"), services: { urlService: ctx.services.urlService, urlReturnToStack: ctx.services.urlReturnToStack @@ -74,8 +76,13 @@ export const getServerSideProps = defineServerSideProps({ function getAuthRedirectDestination(options: { currentLocation: string; tab: string | null; + fromSignup?: boolean; services: { urlService: typeof UrlService; urlReturnToStack: typeof UrlReturnToStack }; }): string { + if (options.tab === "signup" && !options.fromSignup) { + return options.services.urlService.onboarding({ returnTo: "/" }); + } + const redirectUrl = options.tab === "signup" ? options.services.urlService.signup() : options.services.urlService.login(); const returnTo = options.services.urlReturnToStack.getReturnTo(options.currentLocation); const separator = redirectUrl.includes("?") ? "&" : "?"; From 0a32d9746a1cefd17742e94cb15940785d289996 Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Sat, 31 Jan 2026 16:40:05 -0500 Subject: [PATCH 02/15] feat: add auto-switching logic for custodial wallet selection in useManagedWallet hook --- apps/deploy-web/src/hooks/useManagedWallet.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/deploy-web/src/hooks/useManagedWallet.ts b/apps/deploy-web/src/hooks/useManagedWallet.ts index 3e7f3c3813..a236ec6cc8 100644 --- a/apps/deploy-web/src/hooks/useManagedWallet.ts +++ b/apps/deploy-web/src/hooks/useManagedWallet.ts @@ -1,4 +1,4 @@ -import { useEffect, useMemo } from "react"; +import { useEffect, useMemo, useRef } from "react"; import type { ApiManagedWalletOutput } from "@akashnetwork/http-sdk"; import { useAtom } from "jotai"; @@ -18,9 +18,11 @@ export const useManagedWallet = () => { const isLoading = isInitialLoading || isCreating; const [, setIsSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); const selected = getSelectedStorageWallet(); + const hasAutoSwitched = useRef(false); useEffect(() => { - if (selectedWalletType === "custodial" && queried) { + if (!hasAutoSwitched.current && selectedWalletType === "custodial" && queried) { + hasAutoSwitched.current = true; setSelectedWalletType("managed"); } }, [queried, selectedWalletType, setSelectedWalletType]); From 759d53f79a982312431a502017aa2f9712da43ad Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Sat, 31 Jan 2026 20:32:38 -0500 Subject: [PATCH 03/15] refactor: remove wallet-related logic from OnboardingPage component --- apps/deploy-web/src/components/onboarding/OnboardingPage.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx index 058df66195..6bff1b126e 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx @@ -6,7 +6,6 @@ import Link from "next/link"; import { CustomNextSeo } from "@src/components/shared/CustomNextSeo"; import { useServices } from "@src/context/ServicesProvider"; -import { useWallet } from "@src/context/WalletProvider"; import { useReturnTo } from "@src/hooks/useReturnTo"; import { domainName, UrlService } from "@src/utils/urlUtils"; import { OnboardingContainer } from "./OnboardingContainer/OnboardingContainer"; @@ -15,7 +14,6 @@ import { OnboardingView } from "./OnboardingView/OnboardingView"; export const OnboardingPage: FC = () => { const { analyticsService } = useServices(); const { isDeploymentReturnTo } = useReturnTo(); - const { hasManagedWallet, isWalletConnected } = useWallet(); const handleBackToConsole = () => { analyticsService.track("onboarding_back_to_console", { @@ -29,7 +27,7 @@ export const OnboardingPage: FC = () => {
{props => } - {!isDeploymentReturnTo && (hasManagedWallet || isWalletConnected) && ( + {!isDeploymentReturnTo && (
From b054736d0aac326ce09cf8cd0ae9106b478c9d9a Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Sat, 31 Jan 2026 20:34:22 -0500 Subject: [PATCH 04/15] fix: remove redundant query parameter from signup URL in OnboardingContainer --- .../onboarding/OnboardingContainer/OnboardingContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx index 0851d5337c..325822ef80 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx @@ -175,7 +175,7 @@ export const OnboardingContainer: React.FunctionComponent Date: Sat, 31 Jan 2026 21:08:14 -0500 Subject: [PATCH 05/15] refactor: simplify tab switching logic in AuthPage component --- .../src/components/auth/AuthPage/AuthPage.tsx | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx b/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx index 8e44c907c0..68e14d1962 100644 --- a/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx +++ b/apps/deploy-web/src/components/auth/AuthPage/AuthPage.tsx @@ -1,6 +1,6 @@ "use client"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useRef, useState } from "react"; import { Button, Separator, Tabs, TabsContent, TabsList, TabsTrigger } from "@akashnetwork/ui/components"; import { useMutation } from "@tanstack/react-query"; import { DollarSignIcon, RocketIcon, Undo2, ZapIcon } from "lucide-react"; @@ -16,7 +16,6 @@ import { useServices } from "@src/context/ServicesProvider"; import { useWallet as useWalletOriginal } from "@src/context/WalletProvider"; import { useReturnTo } from "@src/hooks/useReturnTo"; import { useUser } from "@src/hooks/useUser"; -import { UrlService } from "@src/utils/urlUtils"; import { AuthLayout } from "../AuthLayout/AuthLayout"; import { ForgotPasswordForm } from "../ForgotPasswordForm/ForgotPasswordForm"; import type { SignInFormValues } from "../SignInForm/SignInForm"; @@ -92,14 +91,9 @@ export function AuthPage({ dependencies: d = DEPENDENCIES }: Props = {}) { }); const activeView = searchParams.get("tab") || "login"; - const isFromSignup = searchParams.has("fromSignup"); const setActiveView = useCallback( (value: string) => { - if (value === "signup") { - router.push(UrlService.onboarding({ returnTo: "/" })); - return; - } - const tabId = value !== "login" && value !== "forgot-password" ? "login" : value; + const tabId = value !== "login" && value !== "signup" && value !== "forgot-password" ? "login" : value; const newSearchParams = new URLSearchParams(searchParams); newSearchParams.set("tab", tabId); resetMutations(); @@ -108,12 +102,6 @@ export function AuthPage({ dependencies: d = DEPENDENCIES }: Props = {}) { [searchParams, router] ); - useEffect(() => { - if (activeView === "signup" && !isFromSignup) { - router.replace(UrlService.onboarding({ returnTo: "/" })); - } - }, [activeView, isFromSignup, router]); - const forgotPassword = useMutation({ async mutationFn(input: { email: string }) { if (!turnstileRef.current) { From 5edd5e8e5f86a8a64bc62879c2875d3a52e181d1 Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 13:35:29 -0500 Subject: [PATCH 06/15] feat: implement logout functionality in OnboardingPage and update related services --- .../OnboardingContainer.spec.tsx | 8 +++--- .../OnboardingContainer.tsx | 18 ++++++++----- .../OnboardingGuard/OnboardingGuard.tsx | 7 ++++- .../components/onboarding/OnboardingPage.tsx | 26 ++++++++----------- .../services/analytics/analytics.service.ts | 2 +- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx index d008d5a681..5357c2bf4a 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx @@ -280,6 +280,9 @@ describe("OnboardingContainer", () => { const mockUseChainParam = jest.fn().mockReturnValue({ minDeposit: { akt: 0.5, usdc: 5 } }); const mockDenomToUdenom = jest.fn().mockImplementation((amount: number) => amount * 1_000_000); const mockErrorHandler = mock(); + const mockTemplateService = { + findById: jest.fn().mockResolvedValue({ deploy: "mock-template-sdl" }) + }; const mockUseServices = jest.fn().mockReturnValue({ analyticsService: mockAnalyticsService, @@ -290,7 +293,8 @@ describe("OnboardingContainer", () => { publicConfig: mockAppConfig, errorHandler: mockErrorHandler, windowLocation, - windowHistory + windowHistory, + template: mockTemplateService }); const mockUseRouter = jest.fn().mockReturnValue(mockRouter); const mockUseWallet = jest.fn().mockReturnValue({ @@ -300,7 +304,6 @@ describe("OnboardingContainer", () => { address: "akash1test", signAndBroadcastTx: mockSignAndBroadcastTx }); - const mockUseTemplates = jest.fn().mockReturnValue({ templates: [] }); const mockUseCertificate = jest.fn().mockReturnValue({ genNewCertificateIfLocalIsInvalid: mockGenNewCertificateIfLocalIsInvalid, updateSelectedCertificate: mockUpdateSelectedCertificate @@ -387,7 +390,6 @@ describe("OnboardingContainer", () => { useServices: mockUseServices, useRouter: mockUseRouter, useWallet: mockUseWallet, - useTemplates: mockUseTemplates, useCertificate: mockUseCertificate, useSnackbar: mockUseSnackbar, useManagedWalletDenom: mockUseManagedWalletDenom, diff --git a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx index 325822ef80..1bdeeda408 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.tsx @@ -14,7 +14,6 @@ import { useManagedWalletDenom } from "@src/hooks/useManagedWalletDenom"; import { useReturnTo } from "@src/hooks/useReturnTo"; import { useUser } from "@src/hooks/useUser"; import { usePaymentMethodsQuery } from "@src/queries/usePaymentQueries"; -import { useTemplates } from "@src/queries/useTemplateQuery"; import { ONBOARDING_STEP_KEY } from "@src/services/storage/keys"; import { RouteStep } from "@src/types/route-steps.type"; import { deploymentData } from "@src/utils/deploymentData"; @@ -53,7 +52,6 @@ const DEPENDENCIES = { useServices, useRouter, useWallet, - useTemplates, useCertificate, useSnackbar, useManagedWalletDenom, @@ -78,9 +76,17 @@ export const OnboardingContainer: React.FunctionComponent t.id === templateConfig.id); + const template = await templateService.findById(templateConfig.id); if (!template || !template.deploy) { const error = new Error(`Template ${templateName} SDL not found`); errorHandler.reportError({ @@ -305,7 +311,7 @@ export const OnboardingContainer: React.FunctionComponent = ({ children }) => { const isExcluded = EXCLUDED_PREFIXES.some(prefix => router.pathname.startsWith(prefix)); useEffect(() => { - if (isUserLoading || isWalletLoading || isExcluded) { + if (isExcluded) { + setIsRedirecting(false); + return; + } + + if (isUserLoading || isWalletLoading) { return; } diff --git a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx index 6bff1b126e..347f4fb584 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx @@ -1,24 +1,22 @@ import React, { type FC } from "react"; import { buttonVariants } from "@akashnetwork/ui/components"; import { cn } from "@akashnetwork/ui/utils"; -import { NavArrowLeft } from "iconoir-react"; -import Link from "next/link"; +import { LogOut } from "iconoir-react"; import { CustomNextSeo } from "@src/components/shared/CustomNextSeo"; import { useServices } from "@src/context/ServicesProvider"; -import { useReturnTo } from "@src/hooks/useReturnTo"; import { domainName, UrlService } from "@src/utils/urlUtils"; import { OnboardingContainer } from "./OnboardingContainer/OnboardingContainer"; import { OnboardingView } from "./OnboardingView/OnboardingView"; export const OnboardingPage: FC = () => { - const { analyticsService } = useServices(); - const { isDeploymentReturnTo } = useReturnTo(); + const { analyticsService, authService } = useServices(); - const handleBackToConsole = () => { - analyticsService.track("onboarding_back_to_console", { + const handleLogout = () => { + analyticsService.track("onboarding_logout", { category: "onboarding" }); + authService.logout(); }; return ( @@ -27,14 +25,12 @@ export const OnboardingPage: FC = () => {
{props => } - {!isDeploymentReturnTo && ( -
- - - Back to Console - -
- )} +
+ +
); diff --git a/apps/deploy-web/src/services/analytics/analytics.service.ts b/apps/deploy-web/src/services/analytics/analytics.service.ts index b5d502a874..62991ffcc6 100644 --- a/apps/deploy-web/src/services/analytics/analytics.service.ts +++ b/apps/deploy-web/src/services/analytics/analytics.service.ts @@ -103,7 +103,7 @@ export type AnalyticsEvent = | "onboarding_email_verified" | "onboarding_payment_method_added" | "onboarding_completed" - | "onboarding_back_to_console"; + | "onboarding_logout"; export type AnalyticsCategory = | "user" From 7527f3d400472856e65bd429a86641950df3b510 Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 13:44:52 -0500 Subject: [PATCH 07/15] refactor: improve auto-switching logic in useManagedWallet hook to check wallet type conditionally --- apps/deploy-web/src/hooks/useManagedWallet.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/deploy-web/src/hooks/useManagedWallet.ts b/apps/deploy-web/src/hooks/useManagedWallet.ts index a236ec6cc8..af18d761f6 100644 --- a/apps/deploy-web/src/hooks/useManagedWallet.ts +++ b/apps/deploy-web/src/hooks/useManagedWallet.ts @@ -21,9 +21,11 @@ export const useManagedWallet = () => { const hasAutoSwitched = useRef(false); useEffect(() => { - if (!hasAutoSwitched.current && selectedWalletType === "custodial" && queried) { + if (!hasAutoSwitched.current && queried) { hasAutoSwitched.current = true; - setSelectedWalletType("managed"); + if (selectedWalletType === "custodial") { + setSelectedWalletType("managed"); + } } }, [queried, selectedWalletType, setSelectedWalletType]); From ee4da9c089ec52fa4c79261902a649c34149eb6c Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 14:48:30 -0500 Subject: [PATCH 08/15] refactor: replace OnboardingGuard with OnboardingRedirectEffect --- .../OnboardingGuard/OnboardingGuard.tsx | 43 ------------------- .../components/onboarding/OnboardingPage.tsx | 27 ++++++++---- .../OnboardingRedirect/OnboardingRedirect.tsx | 17 ++++++++ .../OnboardingRedirectEffect.tsx | 28 ++++++++++++ .../PaymentMethodForm/PaymentMethodForm.tsx | 3 ++ apps/deploy-web/src/hooks/useIsOnboarded.ts | 12 ++++++ apps/deploy-web/src/pages/_app.tsx | 7 ++- .../src/pages/deployments/[dseq]/index.tsx | 5 ++- .../src/pages/deployments/index.tsx | 5 ++- .../src/pages/new-deployment/index.tsx | 5 ++- apps/deploy-web/src/pages/payment.tsx | 5 ++- 11 files changed, 97 insertions(+), 60 deletions(-) delete mode 100644 apps/deploy-web/src/components/onboarding/OnboardingGuard/OnboardingGuard.tsx create mode 100644 apps/deploy-web/src/components/onboarding/OnboardingRedirect/OnboardingRedirect.tsx create mode 100644 apps/deploy-web/src/components/onboarding/OnboardingRedirectEffect/OnboardingRedirectEffect.tsx create mode 100644 apps/deploy-web/src/hooks/useIsOnboarded.ts diff --git a/apps/deploy-web/src/components/onboarding/OnboardingGuard/OnboardingGuard.tsx b/apps/deploy-web/src/components/onboarding/OnboardingGuard/OnboardingGuard.tsx deleted file mode 100644 index 30d36441ad..0000000000 --- a/apps/deploy-web/src/components/onboarding/OnboardingGuard/OnboardingGuard.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; - -import type { FC, ReactNode } from "react"; -import { useEffect, useState } from "react"; -import { useRouter } from "next/router"; - -import { Loading } from "@src/components/layout/Layout"; -import { useWallet } from "@src/context/WalletProvider"; -import { useUser } from "@src/hooks/useUser"; -import { UrlService } from "@src/utils/urlUtils"; - -const EXCLUDED_PREFIXES = ["/signup", "/login", "/api/"]; - -export const OnboardingGuard: FC<{ children: ReactNode }> = ({ children }) => { - const { user, isLoading: isUserLoading } = useUser(); - const { hasManagedWallet, isWalletConnected, isWalletLoading } = useWallet(); - const router = useRouter(); - const [isRedirecting, setIsRedirecting] = useState(false); - - const isExcluded = EXCLUDED_PREFIXES.some(prefix => router.pathname.startsWith(prefix)); - - useEffect(() => { - if (isExcluded) { - setIsRedirecting(false); - return; - } - - if (isUserLoading || isWalletLoading) { - return; - } - - if (user?.userId && !hasManagedWallet && !isWalletConnected) { - setIsRedirecting(true); - router.replace(UrlService.onboarding({ returnTo: router.asPath })); - } - }, [isUserLoading, isWalletLoading, isExcluded, user?.userId, hasManagedWallet, isWalletConnected, router]); - - if (isRedirecting) { - return ; - } - - return <>{children}; -}; diff --git a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx index 347f4fb584..adf1bc88ee 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx @@ -1,4 +1,4 @@ -import React, { type FC } from "react"; +import React, { type FC, useEffect, useState } from "react"; import { buttonVariants } from "@akashnetwork/ui/components"; import { cn } from "@akashnetwork/ui/utils"; import { LogOut } from "iconoir-react"; @@ -11,6 +11,12 @@ import { OnboardingView } from "./OnboardingView/OnboardingView"; export const OnboardingPage: FC = () => { const { analyticsService, authService } = useServices(); + const [isLoginVisible, setIsLoginVisible] = useState(false); + + useEffect(() => { + const timer = setTimeout(() => setIsLoginVisible(true), 1500); + return () => clearTimeout(timer); + }, []); const handleLogout = () => { analyticsService.track("onboarding_logout", { @@ -20,17 +26,20 @@ export const OnboardingPage: FC = () => { }; return ( -
+
-
+
{props => } +
-
- -
+
+
); diff --git a/apps/deploy-web/src/components/onboarding/OnboardingRedirect/OnboardingRedirect.tsx b/apps/deploy-web/src/components/onboarding/OnboardingRedirect/OnboardingRedirect.tsx new file mode 100644 index 0000000000..c90b519ee5 --- /dev/null +++ b/apps/deploy-web/src/components/onboarding/OnboardingRedirect/OnboardingRedirect.tsx @@ -0,0 +1,17 @@ +import { useEffect } from "react"; +import { useRouter } from "next/router"; + +import { Loading } from "@src/components/layout/Layout"; +import { UrlService } from "@src/utils/urlUtils"; + +const OnboardingRedirect = () => { + const router = useRouter(); + + useEffect(() => { + router.replace(UrlService.onboarding({ returnTo: router.asPath })); + }, [router]); + + return ; +}; + +export default OnboardingRedirect; diff --git a/apps/deploy-web/src/components/onboarding/OnboardingRedirectEffect/OnboardingRedirectEffect.tsx b/apps/deploy-web/src/components/onboarding/OnboardingRedirectEffect/OnboardingRedirectEffect.tsx new file mode 100644 index 0000000000..abf353453e --- /dev/null +++ b/apps/deploy-web/src/components/onboarding/OnboardingRedirectEffect/OnboardingRedirectEffect.tsx @@ -0,0 +1,28 @@ +import { useEffect } from "react"; +import { useRouter } from "next/router"; + +import { useWallet } from "@src/context/WalletProvider"; +import { useUser } from "@src/hooks/useUser"; +import { UrlService } from "@src/utils/urlUtils"; + +const EXCLUDED_PREFIXES = ["/signup", "/login", "/api/"]; + +export const OnboardingRedirectEffect = () => { + const { user, isLoading: isUserLoading } = useUser(); + const { hasManagedWallet, isWalletConnected, isWalletLoading } = useWallet(); + const router = useRouter(); + + useEffect(() => { + const isExcluded = EXCLUDED_PREFIXES.some(prefix => router.pathname.startsWith(prefix)); + + if (isExcluded || isUserLoading || isWalletLoading) { + return; + } + + if (user?.userId && !hasManagedWallet && !isWalletConnected) { + router.replace(UrlService.onboarding({ returnTo: router.asPath })); + } + }, [isUserLoading, isWalletLoading, user?.userId, hasManagedWallet, isWalletConnected, router]); + + return null; +}; diff --git a/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx b/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx index a2f85057a2..4ff5bd660b 100644 --- a/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx +++ b/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx @@ -7,6 +7,7 @@ import { StripeInput } from "../StripeInput"; interface PaymentMethodFormProps { onSuccess: (organization?: string) => void; + onReady?: () => void; buttonText?: string; processingText?: string; className?: string; @@ -14,6 +15,7 @@ interface PaymentMethodFormProps { export const PaymentMethodForm: React.FC = ({ onSuccess, + onReady, buttonText = "Add Card", processingText = "Processing...", className = "" @@ -83,6 +85,7 @@ export const PaymentMethodForm: React.FC = ({ options={{ layout: "tabs" }} + onReady={onReady} />
diff --git a/apps/deploy-web/src/hooks/useIsOnboarded.ts b/apps/deploy-web/src/hooks/useIsOnboarded.ts new file mode 100644 index 0000000000..38b30ee82c --- /dev/null +++ b/apps/deploy-web/src/hooks/useIsOnboarded.ts @@ -0,0 +1,12 @@ +import { useWallet } from "@src/context/WalletProvider"; +import { useUser } from "@src/hooks/useUser"; + +export const useIsOnboarded = () => { + const { user, isLoading: isUserLoading } = useUser(); + const { hasManagedWallet, isWalletConnected, isWalletLoading } = useWallet(); + + return { + isLoading: isUserLoading || isWalletLoading, + canVisit: !user?.userId || hasManagedWallet || isWalletConnected + }; +}; diff --git a/apps/deploy-web/src/pages/_app.tsx b/apps/deploy-web/src/pages/_app.tsx index 87624e1f3b..ae2bd93050 100644 --- a/apps/deploy-web/src/pages/_app.tsx +++ b/apps/deploy-web/src/pages/_app.tsx @@ -20,7 +20,7 @@ import NProgress from "nprogress"; import GoogleAnalytics from "@src/components/layout/CustomGoogleAnalytics"; import { CustomIntlProvider } from "@src/components/layout/CustomIntlProvider"; import { PageHead } from "@src/components/layout/PageHead"; -import { OnboardingGuard } from "@src/components/onboarding/OnboardingGuard/OnboardingGuard"; +import { OnboardingRedirectEffect } from "@src/components/onboarding/OnboardingRedirectEffect/OnboardingRedirectEffect"; import { UserProviders } from "@src/components/user/UserProviders/UserProviders"; import { CertificateProvider } from "@src/context/CertificateProvider"; import { CustomChainProvider } from "@src/context/CustomChainProvider"; @@ -61,9 +61,8 @@ const App: React.FunctionComponent = props => { - - - + + diff --git a/apps/deploy-web/src/pages/deployments/[dseq]/index.tsx b/apps/deploy-web/src/pages/deployments/[dseq]/index.tsx index 746d200f3b..53ffbb1771 100644 --- a/apps/deploy-web/src/pages/deployments/[dseq]/index.tsx +++ b/apps/deploy-web/src/pages/deployments/[dseq]/index.tsx @@ -1,9 +1,12 @@ import { z } from "zod"; import { DeploymentDetail } from "@src/components/deployments/DeploymentDetail"; +import OnboardingRedirect from "@src/components/onboarding/OnboardingRedirect/OnboardingRedirect"; +import { Guard } from "@src/hoc/guard/guard.hoc"; +import { useIsOnboarded } from "@src/hooks/useIsOnboarded"; import { defineServerSideProps } from "@src/lib/nextjs/defineServerSideProps/defineServerSideProps"; -export default DeploymentDetail; +export default Guard(DeploymentDetail, useIsOnboarded, OnboardingRedirect); export const getServerSideProps = defineServerSideProps({ route: "/deployments/[dseq]", diff --git a/apps/deploy-web/src/pages/deployments/index.tsx b/apps/deploy-web/src/pages/deployments/index.tsx index fa1c751139..8f5b1d4503 100644 --- a/apps/deploy-web/src/pages/deployments/index.tsx +++ b/apps/deploy-web/src/pages/deployments/index.tsx @@ -1,9 +1,12 @@ import React from "react"; import { DeploymentList } from "@src/components/deployments/DeploymentList"; +import OnboardingRedirect from "@src/components/onboarding/OnboardingRedirect/OnboardingRedirect"; +import { Guard } from "@src/hoc/guard/guard.hoc"; +import { useIsOnboarded } from "@src/hooks/useIsOnboarded"; function DeploymentsPage() { return ; } -export default DeploymentsPage; +export default Guard(DeploymentsPage, useIsOnboarded, OnboardingRedirect); diff --git a/apps/deploy-web/src/pages/new-deployment/index.tsx b/apps/deploy-web/src/pages/new-deployment/index.tsx index 8a5ce223d3..e3490074cc 100644 --- a/apps/deploy-web/src/pages/new-deployment/index.tsx +++ b/apps/deploy-web/src/pages/new-deployment/index.tsx @@ -1,7 +1,10 @@ import { NewDeploymentContainer } from "@src/components/new-deployment/NewDeploymentContainer"; import { createServerSideProps } from "@src/components/new-deployment/NewDeploymentPage/createServerSideProps"; +import OnboardingRedirect from "@src/components/onboarding/OnboardingRedirect/OnboardingRedirect"; import { withSdlBuilder } from "@src/context/SdlBuilderProvider/SdlBuilderProvider"; +import { Guard } from "@src/hoc/guard/guard.hoc"; +import { useIsOnboarded } from "@src/hooks/useIsOnboarded"; -export default withSdlBuilder()(NewDeploymentContainer); +export default Guard(withSdlBuilder()(NewDeploymentContainer), useIsOnboarded, OnboardingRedirect); export const getServerSideProps = createServerSideProps("/new-deployment"); diff --git a/apps/deploy-web/src/pages/payment.tsx b/apps/deploy-web/src/pages/payment.tsx index 0219ca40d5..d40cfd52f9 100644 --- a/apps/deploy-web/src/pages/payment.tsx +++ b/apps/deploy-web/src/pages/payment.tsx @@ -5,6 +5,7 @@ import { useTheme } from "next-themes"; import { useSnackbar } from "notistack"; import Layout from "@src/components/layout/Layout"; +import OnboardingRedirect from "@src/components/onboarding/OnboardingRedirect/OnboardingRedirect"; import { ThreeDSecurePopup } from "@src/components/shared/PaymentMethodForm/ThreeDSecurePopup"; import { PaymentMethodsList } from "@src/components/shared/PaymentMethodsList"; import { Title } from "@src/components/shared/Title"; @@ -13,7 +14,9 @@ import { PaymentSuccessAnimation } from "@src/components/user/payment/PaymentSuc import { usePaymentPolling } from "@src/context/PaymentPollingProvider"; import { useSettings } from "@src/context/SettingsProvider"; import { useWallet } from "@src/context/WalletProvider"; +import { Guard } from "@src/hoc/guard/guard.hoc"; import { use3DSecure } from "@src/hooks/use3DSecure"; +import { useIsOnboarded } from "@src/hooks/useIsOnboarded"; import { useUser } from "@src/hooks/useUser"; import { defineServerSideProps } from "@src/lib/nextjs/defineServerSideProps/defineServerSideProps"; import { redirectIfAccessTokenExpired } from "@src/lib/nextjs/pageGuards/pageGuards"; @@ -340,7 +343,7 @@ const PayPage: React.FunctionComponent = () => { ); }; -export default PayPage; +export default Guard(PayPage, useIsOnboarded, OnboardingRedirect); export const getServerSideProps = defineServerSideProps({ if: redirectIfAccessTokenExpired, From 79f2c63a33696bde6ef0bbe944812c8a221517fc Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:19:51 -0500 Subject: [PATCH 09/15] refactor: consolidate wallet connection logic into WalletConnectionButtons --- .../components/deployments/DeploymentList.tsx | 6 --- .../get-started/GetStartedStepper.tsx | 19 +-------- .../components/home/NoDeploymentsState.tsx | 31 +++++--------- apps/deploy-web/src/components/layout/Nav.tsx | 14 +------ .../src/components/layout/WalletStatus.tsx | 11 +---- .../components/onboarding/OnboardingPage.tsx | 10 +---- .../src/components/shared/ConnectWallet.tsx | 13 ------ .../components/wallet/ConnectWalletButton.tsx | 11 ++++- .../wallet/WalletConnectionButtons.tsx | 41 +++++++++++++++++++ 9 files changed, 67 insertions(+), 89 deletions(-) create mode 100644 apps/deploy-web/src/components/wallet/WalletConnectionButtons.tsx diff --git a/apps/deploy-web/src/components/deployments/DeploymentList.tsx b/apps/deploy-web/src/components/deployments/DeploymentList.tsx index 95b0eb1b36..23a5ad1e55 100644 --- a/apps/deploy-web/src/components/deployments/DeploymentList.tsx +++ b/apps/deploy-web/src/components/deployments/DeploymentList.tsx @@ -23,13 +23,11 @@ import { LinkTo } from "@src/components/shared/LinkTo"; import { useLocalNotes } from "@src/context/LocalNoteProvider"; import { useSettings } from "@src/context/SettingsProvider"; import { useWallet } from "@src/context/WalletProvider"; -import { useCustomUser } from "@src/hooks/useCustomUser"; import { useListSelection } from "@src/hooks/useListSelection/useListSelection"; import { useManagedDeploymentConfirm } from "@src/hooks/useManagedDeploymentConfirm"; import { useDeploymentList } from "@src/queries/useDeploymentQuery"; import { useProviderList } from "@src/queries/useProvidersQuery"; import sdlStore from "@src/store/sdlStore"; -import walletStore from "@src/store/walletStore"; import type { DeploymentDto, NamedDeploymentDto } from "@src/types/deployment"; import { TransactionMessageData } from "@src/utils/TransactionMessageData"; import { UrlService } from "@src/utils/urlUtils"; @@ -59,8 +57,6 @@ export const DeploymentList: React.FunctionComponent = () => { const pageCount = Math.ceil(orderedDeployments.length / pageSize); const [, setDeploySdl] = useAtom(sdlStore.deploySdl); const { closeDeploymentConfirm } = useManagedDeploymentConfirm(); - const [isSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); - const { user } = useCustomUser(); const { selectedItemIds, selectItem, clearSelection } = useListSelection({ ids: currentPageDeployments.map(deployment => deployment.dseq) @@ -217,8 +213,6 @@ export const DeploymentList: React.FunctionComponent = () => { onDeployClick={onDeployClick} hasDeployments={Boolean(deployments && deployments.length > 0)} isWalletConnected={isWalletConnected} - isSignedInWithTrial={isSignedInWithTrial} - hasUser={Boolean(user)} showTemplatesButton /> )} diff --git a/apps/deploy-web/src/components/get-started/GetStartedStepper.tsx b/apps/deploy-web/src/components/get-started/GetStartedStepper.tsx index 505e6204e1..8aca81612c 100644 --- a/apps/deploy-web/src/components/get-started/GetStartedStepper.tsx +++ b/apps/deploy-web/src/components/get-started/GetStartedStepper.tsx @@ -8,23 +8,19 @@ import StepContent from "@mui/material/StepContent"; import StepLabel from "@mui/material/StepLabel"; import Stepper from "@mui/material/Stepper"; import { Check, HandCard, Rocket, WarningCircle, XmarkCircleSolid } from "iconoir-react"; -import { useAtom } from "jotai"; import Link from "next/link"; import { AddFundsLink } from "@src/components/user/AddFundsLink"; -import { ConnectManagedWalletButton } from "@src/components/wallet/ConnectManagedWalletButton"; import { useWallet } from "@src/context/WalletProvider"; import { useChainParam } from "@src/hooks/useChainParam/useChainParam"; -import { useCustomUser } from "@src/hooks/useCustomUser"; import { useWalletBalance } from "@src/hooks/useWalletBalance"; -import walletStore from "@src/store/walletStore"; import { RouteStep } from "@src/types/route-steps.type"; import { udenomToDenom } from "@src/utils/mathHelpers"; import { uaktToAKT } from "@src/utils/priceUtils"; import { UrlService } from "@src/utils/urlUtils"; import LiquidityModal from "../liquidity-modal"; import { ExternalLink } from "../shared/ExternalLink"; -import { ConnectWalletButton } from "../wallet/ConnectWalletButton"; +import { WalletConnectionButtons } from "../wallet/WalletConnectionButtons"; import { QontoConnector, QontoStepIcon } from "./Stepper"; export const GetStartedStepper: React.FunctionComponent = () => { @@ -34,8 +30,6 @@ export const GetStartedStepper: React.FunctionComponent = () => { const { minDeposit } = useChainParam(); const aktBalance = walletBalance ? uaktToAKT(walletBalance.balanceUAKT) : 0; const usdcBalance = walletBalance ? udenomToDenom(walletBalance.balanceUUSDC) : 0; - const [isSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); - const { user } = useCustomUser(); useEffect(() => { const getStartedStep = localStorage.getItem("getStartedStep"); @@ -141,16 +135,7 @@ export const GetStartedStepper: React.FunctionComponent = () => { Billing is not set up
-
- {!isSignedInWithTrial && } - - - {isSignedInWithTrial && !user && ( - - Sign in - - )} -
+
)} diff --git a/apps/deploy-web/src/components/home/NoDeploymentsState.tsx b/apps/deploy-web/src/components/home/NoDeploymentsState.tsx index dd5f70d6fb..cbc3617ba8 100644 --- a/apps/deploy-web/src/components/home/NoDeploymentsState.tsx +++ b/apps/deploy-web/src/components/home/NoDeploymentsState.tsx @@ -1,32 +1,26 @@ "use client"; import React from "react"; -import { Button, buttonVariants, Card, CardContent } from "@akashnetwork/ui/components"; -import { cn } from "@akashnetwork/ui/utils"; +import { Button, Card, CardContent } from "@akashnetwork/ui/components"; import { MultiplePages, Rocket } from "iconoir-react"; +import { useAtom } from "jotai"; import Link from "next/link"; -import { ConnectWalletButton } from "@src/components/wallet/ConnectWalletButton"; +import { WalletConnectionButtons } from "@src/components/wallet/WalletConnectionButtons"; import { useServices } from "@src/context/ServicesProvider"; -import { UrlService } from "@src/utils/urlUtils"; +import { useCustomUser } from "@src/hooks/useCustomUser"; +import walletStore from "@src/store/walletStore"; type Props = { onDeployClick: () => void; hasDeployments?: boolean; isWalletConnected?: boolean; - isSignedInWithTrial?: boolean; - hasUser?: boolean; showTemplatesButton?: boolean; }; -export const NoDeploymentsState: React.FC = ({ - onDeployClick, - hasDeployments = false, - isWalletConnected = true, - isSignedInWithTrial = false, - hasUser = true, - showTemplatesButton = true -}) => { +export const NoDeploymentsState: React.FC = ({ onDeployClick, hasDeployments = false, isWalletConnected = true, showTemplatesButton = true }) => { const { urlService } = useServices(); + const [isSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); + const { user } = useCustomUser(); const title = hasDeployments ? "No active deployments." : "No deployments yet."; @@ -38,7 +32,7 @@ export const NoDeploymentsState: React.FC = ({

{title}

- {isSignedInWithTrial && !hasUser && ( + {isSignedInWithTrial && !user && (

If you are expecting to see some, you may need to sign-in or connect a wallet

)} @@ -66,12 +60,7 @@ export const NoDeploymentsState: React.FC = ({ )}
) : ( -
- - - Sign in - -
+ )} diff --git a/apps/deploy-web/src/components/layout/Nav.tsx b/apps/deploy-web/src/components/layout/Nav.tsx index 99cc7349ab..012334cc2a 100644 --- a/apps/deploy-web/src/components/layout/Nav.tsx +++ b/apps/deploy-web/src/components/layout/Nav.tsx @@ -1,16 +1,12 @@ "use client"; -import { Button, buttonVariants } from "@akashnetwork/ui/components"; +import { Button } from "@akashnetwork/ui/components"; import { cn } from "@akashnetwork/ui/utils"; import type { ClassValue } from "clsx"; import { Menu, Xmark } from "iconoir-react"; -import { useAtom } from "jotai"; import Link from "next/link"; import { ACCOUNT_BAR_HEIGHT } from "@src/config/ui.config"; -import { useCustomUser } from "@src/hooks/useCustomUser"; import useCookieTheme from "@src/hooks/useTheme"; -import walletStore from "@src/store/walletStore"; -import { UrlService } from "@src/utils/urlUtils"; import { AccountMenu } from "./AccountMenu"; import { AkashLogo } from "./AkashLogo"; import { WalletStatus } from "./WalletStatus"; @@ -25,8 +21,6 @@ export const Nav = ({ className?: ClassValue; }>) => { const theme = useCookieTheme(); - const [isSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); - const { user } = useCustomUser(); return (
@@ -47,12 +41,6 @@ export const Nav = ({
- - {isSignedInWithTrial && !user && ( - - Sign in - - )}
diff --git a/apps/deploy-web/src/components/layout/WalletStatus.tsx b/apps/deploy-web/src/components/layout/WalletStatus.tsx index 77fba23330..2b11c6713f 100644 --- a/apps/deploy-web/src/components/layout/WalletStatus.tsx +++ b/apps/deploy-web/src/components/layout/WalletStatus.tsx @@ -5,21 +5,17 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, Spinner } from import { cn } from "@akashnetwork/ui/utils"; import ClickAwayListener from "@mui/material/ClickAwayListener"; import { NavArrowDown, Wallet } from "iconoir-react"; -import { useAtom } from "jotai"; -import { ConnectManagedWalletButton } from "@src/components/wallet/ConnectManagedWalletButton"; import { useWallet } from "@src/context/WalletProvider"; import { getSplitText } from "@src/hooks/useShortText"; import { useWalletBalance } from "@src/hooks/useWalletBalance"; -import walletStore from "@src/store/walletStore"; -import { ConnectWalletButton } from "../wallet/ConnectWalletButton"; import { CustodialWalletPopup } from "../wallet/CustodialWalletPopup"; import { ManagedWalletPopup } from "../wallet/ManagedWalletPopup"; +import { WalletConnectionButtons } from "../wallet/WalletConnectionButtons"; export function WalletStatus() { const { walletName, isWalletLoaded, isWalletConnected, isManaged, isWalletLoading, isTrialing } = useWallet(); const { balance: walletBalance, isLoading: isWalletBalanceLoading } = useWalletBalance(); - const [isSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); const [open, setOpen] = useState(false); const isLoadingBalance = isWalletBalanceLoading && !walletBalance; const isInit = isWalletLoaded && !isWalletLoading && !isLoadingBalance; @@ -89,10 +85,7 @@ export function WalletStatus() {
) : ( -
- {!isSignedInWithTrial && } - -
+ ) ) : (
diff --git a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx index adf1bc88ee..1217fea977 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx @@ -1,4 +1,4 @@ -import React, { type FC, useEffect, useState } from "react"; +import React, { type FC } from "react"; import { buttonVariants } from "@akashnetwork/ui/components"; import { cn } from "@akashnetwork/ui/utils"; import { LogOut } from "iconoir-react"; @@ -11,12 +11,6 @@ import { OnboardingView } from "./OnboardingView/OnboardingView"; export const OnboardingPage: FC = () => { const { analyticsService, authService } = useServices(); - const [isLoginVisible, setIsLoginVisible] = useState(false); - - useEffect(() => { - const timer = setTimeout(() => setIsLoginVisible(true), 1500); - return () => clearTimeout(timer); - }, []); const handleLogout = () => { analyticsService.track("onboarding_logout", { @@ -32,7 +26,7 @@ export const OnboardingPage: FC = () => { {props => }
-
+
); }; diff --git a/apps/deploy-web/src/components/wallet/WalletConnectionButtons.tsx b/apps/deploy-web/src/components/wallet/WalletConnectionButtons.tsx new file mode 100644 index 0000000000..e637df7e32 --- /dev/null +++ b/apps/deploy-web/src/components/wallet/WalletConnectionButtons.tsx @@ -0,0 +1,41 @@ +"use client"; +import React from "react"; +import { buttonVariants } from "@akashnetwork/ui/components"; +import { cn } from "@akashnetwork/ui/utils"; +import { LogIn } from "iconoir-react"; +import { useAtom } from "jotai"; +import Link from "next/link"; + +import { useCustomUser } from "@src/hooks/useCustomUser"; +import walletStore from "@src/store/walletStore"; +import { UrlService } from "@src/utils/urlUtils"; +import { ConnectManagedWalletButton } from "./ConnectManagedWalletButton"; +import { ConnectWalletButton } from "./ConnectWalletButton"; + +interface WalletConnectionButtonsProps { + className?: string; + connectManagedWalletButtonClassName?: string; + connectWalletButtonClassName?: string; +} + +export const WalletConnectionButtons: React.FC = ({ + className, + connectManagedWalletButtonClassName, + connectWalletButtonClassName +}) => { + const [isSignedInWithTrial] = useAtom(walletStore.isSignedInWithTrial); + const { user } = useCustomUser(); + + return ( +
+ {!isSignedInWithTrial && } + {isSignedInWithTrial && !user && ( + + + Sign in + + )} + +
+ ); +}; From 451f6bb74dfbf09079d61a5924d274897f21c01e Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:20:44 -0500 Subject: [PATCH 10/15] refactor: update onReady prop type in PaymentMethodForm to match PaymentElement interface --- .../components/shared/PaymentMethodForm/PaymentMethodForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx b/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx index 4ff5bd660b..7cd603bbb6 100644 --- a/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx +++ b/apps/deploy-web/src/components/shared/PaymentMethodForm/PaymentMethodForm.tsx @@ -7,7 +7,7 @@ import { StripeInput } from "../StripeInput"; interface PaymentMethodFormProps { onSuccess: (organization?: string) => void; - onReady?: () => void; + onReady?: React.ComponentProps["onReady"]; buttonText?: string; processingText?: string; className?: string; From f878335a0273e4cf826b0f570a6354b9fdc5cf2f Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 19:49:04 -0500 Subject: [PATCH 11/15] refactor: streamline onboarding components --- .../components/home/NoDeploymentsState.tsx | 2 +- .../CreateLease/CreateLease.tsx | 45 ++------ .../components/onboarding/OnboardingPage.tsx | 23 ---- .../OnboardingView/OnboardingView.tsx | 32 +++++- .../steps/WelcomeStep/TrialStatusBar.tsx | 31 ++---- .../steps/WelcomeStep/WelcomeStep.tsx | 105 ++++++++++-------- 6 files changed, 111 insertions(+), 127 deletions(-) diff --git a/apps/deploy-web/src/components/home/NoDeploymentsState.tsx b/apps/deploy-web/src/components/home/NoDeploymentsState.tsx index cbc3617ba8..8dc692e61a 100644 --- a/apps/deploy-web/src/components/home/NoDeploymentsState.tsx +++ b/apps/deploy-web/src/components/home/NoDeploymentsState.tsx @@ -33,7 +33,7 @@ export const NoDeploymentsState: React.FC = ({ onDeployClick, hasDeployme

{title}

{isSignedInWithTrial && !user && ( -

If you are expecting to see some, you may need to sign-in or connect a wallet

+

If you are expecting to see some, you may need to sign in or connect a wallet

)} {showTemplatesButton && ( diff --git a/apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx b/apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx index c157f503e1..d8f0aed411 100644 --- a/apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx +++ b/apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx @@ -37,7 +37,6 @@ import { useWallet } from "@src/context/WalletProvider"; import { useManagedDeploymentConfirm } from "@src/hooks/useManagedDeploymentConfirm"; import { useWhen } from "@src/hooks/useWhen"; import { useBidList } from "@src/queries/useBidQuery"; -import { useBlock } from "@src/queries/useBlocksQuery"; import { useDeploymentDetail } from "@src/queries/useDeploymentQuery"; import { useProviderList } from "@src/queries/useProvidersQuery"; import type { SendManifestToProviderOptions } from "@src/services/provider-proxy/provider-proxy.service"; @@ -99,7 +98,6 @@ export const DEPENDENCIES = { useSnackbar, useManagedDeploymentConfirm, useRouter, - useBlock, useSettings }; @@ -109,7 +107,6 @@ const REFRESH_BIDS_INTERVAL = 7000; const MAX_NUM_OF_BID_REQUESTS = Math.floor((5.5 * 60 * 1000) / REFRESH_BIDS_INTERVAL); // Show a warning after 1 minute const WARNING_NUM_OF_BID_REQUESTS = Math.round((60 * 1000) / REFRESH_BIDS_INTERVAL); -const TRIAL_SIGNUP_WARNING_TIMEOUT = 33_000; export const CreateLease: React.FunctionComponent = ({ dseq, dependencies: d = DEPENDENCIES }) => { const { settings } = d.useSettings(); @@ -297,25 +294,6 @@ export const CreateLease: React.FunctionComponent = ({ dseq, dependencies // eslint-disable-next-line react-hooks/exhaustive-deps }, [search, bids, providers, isFilteringFavorites, isFilteringAudited, favoriteProviders]); - const [zeroBidsForTrialWarningDisplayed, setZeroBidsForTrialWarningDisplayed] = useState(false); - const { data: block } = d.useBlock(dseq); - - useEffect(() => { - if (!isTrialing || numberOfRequests === 0 || (bids && bids.length > 0)) { - setZeroBidsForTrialWarningDisplayed(false); - return; - } - - const timerId = setTimeout(() => { - if (block) { - const blockTime = new Date(block.block.header.time).getTime(); - setZeroBidsForTrialWarningDisplayed(Date.now() - blockTime > TRIAL_SIGNUP_WARNING_TIMEOUT); - } - }, 1000); - - return () => clearTimeout(timerId); - }, [block, bids, isTrialing, numberOfRequests]); - const selectBid = (bid: BidDto) => { setSelectedBids(prev => ({ ...prev, [bid.gseq]: bid })); }; @@ -463,7 +441,7 @@ export const CreateLease: React.FunctionComponent = ({ dseq, dependencies )} - {!settings.isBlockchainDown && !zeroBidsForTrialWarningDisplayed && warningRequestsReached && !maxRequestsReached && (bids?.length || 0) === 0 && ( + {!settings.isBlockchainDown && warningRequestsReached && !maxRequestsReached && (bids?.length || 0) === 0 && (
There should be bids by now... You can wait longer in case a bid shows up or close the deployment and try again with a different configuration. @@ -476,18 +454,19 @@ export const CreateLease: React.FunctionComponent = ({ dseq, dependencies
)} - {!settings.isBlockchainDown && - (isLoadingBids || (bids?.length || 0) === 0) && - !maxRequestsReached && - !isSendingManifest && - !zeroBidsForTrialWarningDisplayed && ( -
- -
Waiting for bids...
+ {!settings.isBlockchainDown && (isLoadingBids || (bids?.length || 0) === 0) && !maxRequestsReached && !isSendingManifest && ( +
+ +
Waiting for bids...
+
+ + Close Deployment +
- )} +
+ )} - {!settings.isBlockchainDown && !zeroBidsForTrialWarningDisplayed && maxRequestsReached && (bids?.length || 0) === 0 && ( + {!settings.isBlockchainDown && maxRequestsReached && (bids?.length || 0) === 0 && (
There's no bid for the current deployment. You can close the deployment and try again with a different configuration. diff --git a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx index 1217fea977..250aa55f5d 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingPage.tsx @@ -1,40 +1,17 @@ import React, { type FC } from "react"; -import { buttonVariants } from "@akashnetwork/ui/components"; -import { cn } from "@akashnetwork/ui/utils"; -import { LogOut } from "iconoir-react"; import { CustomNextSeo } from "@src/components/shared/CustomNextSeo"; -import { useServices } from "@src/context/ServicesProvider"; import { domainName, UrlService } from "@src/utils/urlUtils"; import { OnboardingContainer } from "./OnboardingContainer/OnboardingContainer"; import { OnboardingView } from "./OnboardingView/OnboardingView"; export const OnboardingPage: FC = () => { - const { analyticsService, authService } = useServices(); - - const handleLogout = () => { - analyticsService.track("onboarding_logout", { - category: "onboarding" - }); - authService.logout(); - }; - return (
{props => }
- -
- -
); }; diff --git a/apps/deploy-web/src/components/onboarding/OnboardingView/OnboardingView.tsx b/apps/deploy-web/src/components/onboarding/OnboardingView/OnboardingView.tsx index e1b7d78faf..a28d422ec4 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingView/OnboardingView.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingView/OnboardingView.tsx @@ -1,6 +1,11 @@ import type { FC } from "react"; import React from "react"; +import { buttonVariants } from "@akashnetwork/ui/components"; +import { cn } from "@akashnetwork/ui/utils"; +import { LogOut } from "iconoir-react"; +import { useServices } from "@src/context/ServicesProvider"; +import { useUser } from "@src/hooks/useUser"; import { OnboardingStepIndex } from "../OnboardingContainer/OnboardingContainer"; import { type OnboardingStep, OnboardingStepper } from "../OnboardingStepper/OnboardingStepper"; import { EmailVerificationContainer } from "../steps/EmailVerificationContainer/EmailVerificationContainer"; @@ -66,5 +71,30 @@ export const OnboardingView: FC = ({ } ]; - return ; + const { analyticsService, authService } = useServices(); + const { user } = useUser(); + + const handleLogout = () => { + analyticsService.track("onboarding_logout", { + category: "onboarding" + }); + authService.logout(); + }; + + return ( + <> + + {user && currentStep !== OnboardingStepIndex.WELCOME && ( +
+ +
+ )} + + ); }; diff --git a/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/TrialStatusBar.tsx b/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/TrialStatusBar.tsx index 11621aa72d..c25679628c 100644 --- a/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/TrialStatusBar.tsx +++ b/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/TrialStatusBar.tsx @@ -1,13 +1,13 @@ "use client"; import React from "react"; import { FormattedDate } from "react-intl"; -import { Card, Progress, Skeleton } from "@akashnetwork/ui/components"; -import { InfoCircle } from "iconoir-react"; +import { Card, Skeleton } from "@akashnetwork/ui/components"; +import { Check, InfoCircle } from "iconoir-react"; import { useTrialBalance } from "@src/hooks/useTrialBalance"; export const TrialStatusBar: React.FC = () => { - const { total: TRIAL_TOTAL, remaining: creditsRemaining, used: creditsUsed, remainingPercentage, isLoading, trialEndDate, daysRemaining } = useTrialBalance(); + const { remaining: creditsRemaining, isLoading, trialEndDate, daysRemaining } = useTrialBalance(); if (isLoading) { return ( @@ -24,14 +24,6 @@ export const TrialStatusBar: React.FC = () => {
- -
- -
- - -
-
); @@ -41,8 +33,11 @@ export const TrialStatusBar: React.FC = () => {
-
- Trial Active +
+ + + Trial Active +
Free Trial Credits: ${creditsRemaining.toFixed(2)}
@@ -57,16 +52,6 @@ export const TrialStatusBar: React.FC = () => { Deployments last for maximum 1 day during trial
- -
- -
- ${creditsUsed.toFixed(2)} used - - ${creditsRemaining.toFixed(2)} remaining of ${TRIAL_TOTAL.toFixed(2)} - -
-
); diff --git a/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/WelcomeStep.tsx b/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/WelcomeStep.tsx index ca411d2ae3..a0697b9581 100644 --- a/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/WelcomeStep.tsx +++ b/apps/deploy-web/src/components/onboarding/steps/WelcomeStep/WelcomeStep.tsx @@ -1,6 +1,7 @@ "use client"; import React, { useState } from "react"; import { Button, Spinner } from "@akashnetwork/ui/components"; +import { ArrowRight } from "iconoir-react"; import Image from "next/image"; import { useServices } from "@src/context/ServicesProvider"; @@ -55,56 +56,68 @@ export const WelcomeStep: React.FunctionComponent = ({ onCompl
-
-

Welcome to Akash Console

- {isDeploymentReturnTo ? ( -

You're all set! Continue to complete your deployment.

- ) : ( -

Choose a template below to launch your first app in seconds.

- )} -
- {isDeploymentReturnTo ? ( -
- -
- ) : ( -
- } - title="Hello Akash!" - description={ +
+
+

Welcome to Akash Console

+

You're all set! Continue to complete your deployment.

+
+
+ ) : ( + <> +
+

Welcome to Akash Console

+

Choose a template below to launch your first app in seconds.

+
+
+ } + title="Hello Akash!" + description={ + <> + A simple web app powered by Next.js, perfect for your first deployment on Akash. View and explore the full source code{" "} + + here + + . + + } + onDeploy={() => deployTemplate("hello-akash")} + disabled={isDeploying} + isLoading={deployingTemplate === "hello-akash"} + /> + } + title="ComfyUI" + description="A powerful, modular Stable Diffusion tool that lets you build and run advanced image workflows using a visual, node-based interface." + onDeploy={() => deployTemplate("comfyui")} + disabled={isDeploying} + isLoading={deployingTemplate === "comfyui"} + /> + } + title="Llama-3.1-8b" + description="A cutting-edge language model built for fast, context-aware text generation. Access a wide range of advanced language tasks." + onDeploy={() => deployTemplate("llama-3.1-8b")} + disabled={isDeploying} + isLoading={deployingTemplate === "llama-3.1-8b"} + /> +
+ )}
); From 4b62fcb0e287bc681565ad814eed8e2b8e48863a Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Mon, 2 Feb 2026 20:24:30 -0500 Subject: [PATCH 12/15] fix: remove redundant query parameter from login URL in OnboardingContainer tests --- .../onboarding/OnboardingContainer/OnboardingContainer.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx index 5357c2bf4a..e79c164fa7 100644 --- a/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx +++ b/apps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsx @@ -79,7 +79,7 @@ describe("OnboardingContainer", () => { category: "onboarding" }); expect(mockUrlService.newSignup).toHaveBeenCalledWith({ fromSignup: "true" }); - expect(mockRouter.push).toHaveBeenCalledWith("/login?tab=signup&fromSignup=true"); + expect(mockRouter.push).toHaveBeenCalledWith("/login?tab=signup"); }); it("should track analytics when payment method is completed", async () => { From f831f1d280310e78c88ee8d8fec5b7a4e769d0e9 Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:36:26 -0500 Subject: [PATCH 13/15] refactor: enhance useManagedWallet --- apps/deploy-web/src/hooks/useManagedWallet.ts | 6 ++---- apps/deploy-web/src/services/auth/auth/auth.service.ts | 3 ++- apps/deploy-web/src/services/storage/keys.ts | 1 + apps/deploy-web/src/store/walletStore.ts | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/deploy-web/src/hooks/useManagedWallet.ts b/apps/deploy-web/src/hooks/useManagedWallet.ts index af18d761f6..ecf9b65202 100644 --- a/apps/deploy-web/src/hooks/useManagedWallet.ts +++ b/apps/deploy-web/src/hooks/useManagedWallet.ts @@ -21,11 +21,9 @@ export const useManagedWallet = () => { const hasAutoSwitched = useRef(false); useEffect(() => { - if (!hasAutoSwitched.current && queried) { + if (!hasAutoSwitched.current && queried && selectedWalletType === "custodial") { + setSelectedWalletType("managed"); hasAutoSwitched.current = true; - if (selectedWalletType === "custodial") { - setSelectedWalletType("managed"); - } } }, [queried, selectedWalletType, setSelectedWalletType]); diff --git a/apps/deploy-web/src/services/auth/auth/auth.service.ts b/apps/deploy-web/src/services/auth/auth/auth.service.ts index 68931d9ef6..d12b740815 100644 --- a/apps/deploy-web/src/services/auth/auth/auth.service.ts +++ b/apps/deploy-web/src/services/auth/auth/auth.service.ts @@ -1,6 +1,6 @@ import type { HttpClient } from "@akashnetwork/http-sdk"; -import { ONBOARDING_STEP_KEY } from "../../storage/keys"; +import { IS_SIGNED_IN_WITH_TRIAL_KEY, ONBOARDING_STEP_KEY } from "../../storage/keys"; export class AuthService { constructor( @@ -46,6 +46,7 @@ export class AuthService { logout() { this.localStorage.removeItem(ONBOARDING_STEP_KEY); + this.localStorage.removeItem(IS_SIGNED_IN_WITH_TRIAL_KEY); this.location.assign(this.urlService.logout()); } } diff --git a/apps/deploy-web/src/services/storage/keys.ts b/apps/deploy-web/src/services/storage/keys.ts index 0ae055c131..245dc6aca9 100644 --- a/apps/deploy-web/src/services/storage/keys.ts +++ b/apps/deploy-web/src/services/storage/keys.ts @@ -1 +1,2 @@ export const ONBOARDING_STEP_KEY = "onboardingStep"; +export const IS_SIGNED_IN_WITH_TRIAL_KEY = "isSignedInWithTrial"; diff --git a/apps/deploy-web/src/store/walletStore.ts b/apps/deploy-web/src/store/walletStore.ts index c008e63ed9..4153e6bb27 100644 --- a/apps/deploy-web/src/store/walletStore.ts +++ b/apps/deploy-web/src/store/walletStore.ts @@ -2,8 +2,9 @@ import { atom } from "jotai"; import { atomWithStorage } from "jotai/utils"; import type { WalletBalance } from "@src/hooks/useWalletBalance"; +import { IS_SIGNED_IN_WITH_TRIAL_KEY } from "@src/services/storage/keys"; -const isSignedInWithTrial = atomWithStorage("isSignedInWithTrial", false); +const isSignedInWithTrial = atomWithStorage(IS_SIGNED_IN_WITH_TRIAL_KEY, false); const selectedWalletType = atomWithStorage<"managed" | "custodial">("selectedWalletType", "custodial"); const isWalletModalOpen = atom(false); const balance = atom(null); From 18699b09910391f9737a5f5b53b3c26228afed7c Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:42:21 -0500 Subject: [PATCH 14/15] refactor: adjust auto-switching logic in useManagedWallet to conditionally set wallet type --- apps/deploy-web/src/hooks/useManagedWallet.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/deploy-web/src/hooks/useManagedWallet.ts b/apps/deploy-web/src/hooks/useManagedWallet.ts index ecf9b65202..af18d761f6 100644 --- a/apps/deploy-web/src/hooks/useManagedWallet.ts +++ b/apps/deploy-web/src/hooks/useManagedWallet.ts @@ -21,9 +21,11 @@ export const useManagedWallet = () => { const hasAutoSwitched = useRef(false); useEffect(() => { - if (!hasAutoSwitched.current && queried && selectedWalletType === "custodial") { - setSelectedWalletType("managed"); + if (!hasAutoSwitched.current && queried) { hasAutoSwitched.current = true; + if (selectedWalletType === "custodial") { + setSelectedWalletType("managed"); + } } }, [queried, selectedWalletType, setSelectedWalletType]); From 5a009fece6ef9ed3d0f73584926a0df823731619 Mon Sep 17 00:00:00 2001 From: Maxime Beauchamp <15185355+baktun14@users.noreply.github.com> Date: Tue, 3 Feb 2026 10:53:57 -0500 Subject: [PATCH 15/15] Revert "refactor: enhance useManagedWallet" This reverts commit f831f1d280310e78c88ee8d8fec5b7a4e769d0e9. --- apps/deploy-web/src/services/auth/auth/auth.service.ts | 3 +-- apps/deploy-web/src/services/storage/keys.ts | 1 - apps/deploy-web/src/store/walletStore.ts | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/deploy-web/src/services/auth/auth/auth.service.ts b/apps/deploy-web/src/services/auth/auth/auth.service.ts index d12b740815..68931d9ef6 100644 --- a/apps/deploy-web/src/services/auth/auth/auth.service.ts +++ b/apps/deploy-web/src/services/auth/auth/auth.service.ts @@ -1,6 +1,6 @@ import type { HttpClient } from "@akashnetwork/http-sdk"; -import { IS_SIGNED_IN_WITH_TRIAL_KEY, ONBOARDING_STEP_KEY } from "../../storage/keys"; +import { ONBOARDING_STEP_KEY } from "../../storage/keys"; export class AuthService { constructor( @@ -46,7 +46,6 @@ export class AuthService { logout() { this.localStorage.removeItem(ONBOARDING_STEP_KEY); - this.localStorage.removeItem(IS_SIGNED_IN_WITH_TRIAL_KEY); this.location.assign(this.urlService.logout()); } } diff --git a/apps/deploy-web/src/services/storage/keys.ts b/apps/deploy-web/src/services/storage/keys.ts index 245dc6aca9..0ae055c131 100644 --- a/apps/deploy-web/src/services/storage/keys.ts +++ b/apps/deploy-web/src/services/storage/keys.ts @@ -1,2 +1 @@ export const ONBOARDING_STEP_KEY = "onboardingStep"; -export const IS_SIGNED_IN_WITH_TRIAL_KEY = "isSignedInWithTrial"; diff --git a/apps/deploy-web/src/store/walletStore.ts b/apps/deploy-web/src/store/walletStore.ts index 4153e6bb27..c008e63ed9 100644 --- a/apps/deploy-web/src/store/walletStore.ts +++ b/apps/deploy-web/src/store/walletStore.ts @@ -2,9 +2,8 @@ import { atom } from "jotai"; import { atomWithStorage } from "jotai/utils"; import type { WalletBalance } from "@src/hooks/useWalletBalance"; -import { IS_SIGNED_IN_WITH_TRIAL_KEY } from "@src/services/storage/keys"; -const isSignedInWithTrial = atomWithStorage(IS_SIGNED_IN_WITH_TRIAL_KEY, false); +const isSignedInWithTrial = atomWithStorage("isSignedInWithTrial", false); const selectedWalletType = atomWithStorage<"managed" | "custodial">("selectedWalletType", "custodial"); const isWalletModalOpen = atom(false); const balance = atom(null);