diff --git a/packages/keychain/src/hooks/analytics.ts b/packages/keychain/src/hooks/analytics.ts index 64083c3cd..27e47a6af 100644 --- a/packages/keychain/src/hooks/analytics.ts +++ b/packages/keychain/src/hooks/analytics.ts @@ -1,5 +1,5 @@ -import { useRouter } from "next/router"; import { useCallback } from "react"; +import { useLocation } from "react-router-dom"; export interface AnalyticsEvent { type: @@ -17,12 +17,12 @@ export interface AnalyticsEvent { } export const useAnalytics = () => { - const router = useRouter(); + const { pathname } = useLocation(); const event = useCallback( ({ type, payload, address }: AnalyticsEvent) => { - log(type, { address, path: router.pathname, ...payload }); + log(type, { address, path: pathname, ...payload }); }, - [router], + [pathname], ); return { diff --git a/packages/keychain/src/hooks/transaction.ts b/packages/keychain/src/hooks/transaction.ts index e7f33b9d4..4dbc55793 100644 --- a/packages/keychain/src/hooks/transaction.ts +++ b/packages/keychain/src/hooks/transaction.ts @@ -1,6 +1,6 @@ import { useState, useEffect } from "react"; -import { useRouter } from "next/router"; import { constants } from "starknet"; +import { useSearchParams } from "react-router-dom"; export type Transaction = { name: string; @@ -11,20 +11,20 @@ export function useUrlTxns(): { chainId?: constants.StarknetChainId; txns: Transaction[]; } { - const router = useRouter(); + const [searchParams] = useSearchParams(); const [chainId, setChainId] = useState(); const [txns, setTxns] = useState([]); useEffect(() => { - const { chainId, txns: raw } = router.query; - if (!router.isReady) { - return; + const chainId = searchParams.get("chainId"); + const raw = searchParams.get("txns"); + if (chainId) { + setChainId( + chainId + ? (chainId as constants.StarknetChainId) + : constants.StarknetChainId.SN_SEPOLIA, + ); } - setChainId( - chainId - ? (chainId as constants.StarknetChainId) - : constants.StarknetChainId.SN_SEPOLIA, - ); if (!raw) { return; @@ -32,7 +32,7 @@ export function useUrlTxns(): { const res = JSON.parse(raw as string) as Transaction[]; setTxns(res); - }, [router.isReady, router.query]); + }, [searchParams]); return { chainId, diff --git a/packages/keychain/src/pages/authenticate.tsx b/packages/keychain/src/pages/authenticate.tsx index ebaabe327..f87a09b6e 100644 --- a/packages/keychain/src/pages/authenticate.tsx +++ b/packages/keychain/src/pages/authenticate.tsx @@ -1,36 +1,35 @@ -import { useRouter } from "next/router"; import { AuthAction, Authenticate as AuthComponent, } from "@/components/connect"; import { constants } from "starknet"; import { useEffect, useState } from "react"; +import { useNavigate, useSearchParams } from "react-router-dom"; // auth page used for externally embedded keychain export function Authenticate() { - const router = useRouter(); + const [searchParams] = useSearchParams(); const [params, setParams] = useState<{ name: string; action: string; - network?: string; + network: string | null; }>(); + const navigate = useNavigate(); useEffect(() => { - if (router.isReady && !params) { - const { name, action, network } = router.query as { - name: string; - action: string; - network?: string; - }; - - if (name && action) { - setParams({ name, action, network }); + if (params) { + return; + } + const name = searchParams.get("name"); + const action = searchParams.get("action"); + const network = searchParams.get("network"); + if (name && action) { + setParams({ name, action, network }); - // Remove query params to avoid issues with password managers - router.replace(router.pathname, undefined, { shallow: true }); - } + // Remove query params to avoid issues with password managers + navigate("."); } - }, [router.isReady, params]); + }, [params, searchParams, navigate]); if (!params) { return null; @@ -46,7 +45,7 @@ export function Authenticate() { return window.close(); } - router.replace(`${import.meta.env.VITE_ADMIN_URL}/profile`); + navigate(`${import.meta.env.VITE_ADMIN_URL}/profile`); }} /> ); diff --git a/packages/keychain/src/pages/failure.tsx b/packages/keychain/src/pages/failure.tsx index facfa33bd..e80702cfb 100644 --- a/packages/keychain/src/pages/failure.tsx +++ b/packages/keychain/src/pages/failure.tsx @@ -2,9 +2,9 @@ import { Container } from "@/components/layout"; import { AlertIcon, ExternalIcon } from "@cartridge/ui"; -import { Link, Text } from "@chakra-ui/react"; -import NextLink from "next/link"; +import { Link as UILink, Text } from "@chakra-ui/react"; import { CARTRIDGE_DISCORD_LINK } from "@/const"; +import { Link } from "react-router-dom"; export default function Failure() { return ( @@ -18,8 +18,8 @@ export default function Failure() { If this problem persists swing by the Cartridge support channel on{" "} - Discord - + } diff --git a/packages/keychain/src/pages/session.tsx b/packages/keychain/src/pages/session.tsx index ef2dc6b4f..98736a74d 100644 --- a/packages/keychain/src/pages/session.tsx +++ b/packages/keychain/src/pages/session.tsx @@ -7,11 +7,11 @@ import { } from "@/components/connect"; import { useConnection } from "@/hooks/connection"; -import { useRouter } from "next/router"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { LoginMode } from "@/components/connect/types"; import { SESSION_EXPIRATION } from "@/const"; import { PageLoading } from "@/components/Loading"; +import { useNavigate, useSearchParams } from "react-router-dom"; type SessionResponse = { username: string; @@ -22,19 +22,28 @@ type SessionResponse = { alreadyRegistered?: boolean; }; -type SessionQueryParams = Record & { +type SessionQueryParams = { public_key: string; - callback_uri?: string; - redirect_uri?: string; - redirect_query_name?: string; + callback_uri: string | null; + redirect_uri: string | null; + redirect_query_name: string | null; }; /** This page is for registering session */ export default function Session() { - const router = useRouter(); - const queries = router.query as SessionQueryParams; + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const queries: SessionQueryParams = useMemo( + () => ({ + public_key: searchParams.get("public_key")!, + callback_uri: searchParams.get("callback_uri"), + redirect_uri: searchParams.get("redirect_uri"), + redirect_query_name: searchParams.get("redirect_query_name"), + }), + [searchParams], + ); const { controller, policies, origin } = useConnection(); const [isLoading, setIsLoading] = useState(true); @@ -46,7 +55,7 @@ export default function Session() { const onCallback = useCallback( async (response: SessionResponse) => { if (!queries.callback_uri && !queries.redirect_uri) { - router.replace(`/failure`); + navigate("/failure"); return; } @@ -70,17 +79,17 @@ export default function Session() { }); if (res.ok) { - return router.replace({ - pathname: "/success", - query: { + navigate( + `/success?${{ title: "Session Registered!", description: "Return to your terminal to continue", - }, - }); + }.toString()}`, + ); + return; } } catch (e) { console.error("failed to call the callback url", e); - router.replace(`/failure`); + navigate("/failure"); } return; @@ -89,10 +98,10 @@ export default function Session() { if (queries.redirect_uri) { const url = decodeURIComponent(queries.redirect_uri); const query_name = queries.redirect_query_name ?? "session"; - router.replace(`${url}?${query_name}=${encodedResponse}`); + navigate(`${url}?${query_name}=${encodedResponse}`); } }, - [router, queries], + [navigate, queries], ); // Handler when user clicks the Create button diff --git a/packages/keychain/src/pages/slot/consent.tsx b/packages/keychain/src/pages/slot/consent.tsx index 127e86d61..c32aa1415 100644 --- a/packages/keychain/src/pages/slot/consent.tsx +++ b/packages/keychain/src/pages/slot/consent.tsx @@ -1,33 +1,33 @@ import Controller from "@/utils/controller"; import { Button, Text } from "@chakra-ui/react"; import { Container, Footer } from "@/components/layout"; -import { useRouter } from "next/router"; import { useCallback, useEffect } from "react"; +import { useNavigate, useSearchParams } from "react-router-dom"; export function Consent() { - const router = useRouter(); + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const callback_uri = searchParams.get("callback_uri")!; const onSubmit = useCallback(async () => { - const redirect_uri = encodeURIComponent( - router.query.callback_uri as string, - ); + const redirect_uri = encodeURIComponent(callback_uri); const url = `${ import.meta.env.VITE_CARTRIDGE_API_URL }/oauth2/auth?client_id=cartridge&redirect_uri=${redirect_uri}`; window.location.href = url; - }, [router.query.callback_uri]); + }, [callback_uri]); const onDeny = useCallback(async () => { - const url = decodeURIComponent(router.query.callback_uri as string); + const url = decodeURIComponent(callback_uri); window.location.href = url; - }, [router.query.callback_uri]); + }, [callback_uri]); useEffect(() => { if (!Controller.fromStore(import.meta.env.VITE_ORIGIN!)) { - router.replace("/slot/auth"); + navigate("/slot/auth"); } - }, [router]); + }, [navigate]); return ( { if (user && controller) { - const query = Object.entries(router.query).reduce( + const query = Array.from(searchParams.entries()).reduce( (prev, [key, val], i) => i === 0 ? `?${key}=${val}` : `${prev}&${key}=${val}`, "", ); - router.replace(`/slot/consent${query}`); + navigate(`/slot/consent${query}`); } - }, [user, controller, router]); + }, [user, controller, navigate, searchParams]); if (!isFetched) { return ; diff --git a/packages/keychain/src/pages/success.tsx b/packages/keychain/src/pages/success.tsx index f9efb2c54..7f4e77170 100644 --- a/packages/keychain/src/pages/success.tsx +++ b/packages/keychain/src/pages/success.tsx @@ -2,11 +2,12 @@ import { Container } from "@/components/layout"; import { SparklesDuoIcon } from "@cartridge/ui"; -import { useRouter } from "next/router"; +import { useSearchParams } from "react-router-dom"; export default function Success() { - const router = useRouter(); - const { title, description } = router.query; + const [searchParams] = useSearchParams(); + const title = searchParams.get("title"); + const description = searchParams.get("description"); return (