From 909d241ada26014cee6efc9f235fe30467a2dfb5 Mon Sep 17 00:00:00 2001 From: yjin Date: Sun, 5 Jan 2025 22:25:57 +0900 Subject: [PATCH] fix: [GSW-2040] Refreshing causes wallet-client to be initialized --- .../web/src/hooks/wallet/data/use-wallet.ts | 36 ++++++++++++++++--- .../SocialWalletProvider.tsx | 32 ++++++++++++++--- packages/web/src/states/common.ts | 2 ++ packages/web/src/utils/transaction-utils.ts | 23 ++++++++++++ 4 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 packages/web/src/utils/transaction-utils.ts diff --git a/packages/web/src/hooks/wallet/data/use-wallet.ts b/packages/web/src/hooks/wallet/data/use-wallet.ts index 8e05eb208..e132f02f0 100644 --- a/packages/web/src/hooks/wallet/data/use-wallet.ts +++ b/packages/web/src/hooks/wallet/data/use-wallet.ts @@ -6,10 +6,18 @@ import { useAtom } from "jotai"; import { useCallback, useEffect, useMemo } from "react"; import { NetworkData } from "@constants/chains.constant"; import * as uuid from "uuid"; -import { ACCOUNT_SESSION_INFO_KEY, GNOSWAP_SESSION_ID_KEY, GNOWSWAP_CONNECTED_KEY } from "@states/common"; +import { + ACCOUNT_SESSION_INFO_KEY, + GNOSWAP_SESSION_ID_KEY, + GNOSWAP_SOCIAL_LOGIN_TYPE_KEY, + GNOSWAP_WALLET_TYPE_KEY, + GNOWSWAP_CONNECTED_KEY, +} from "@states/common"; import { useQueryClient } from "@tanstack/react-query"; import { SUPPORT_CHAIN_IDS, DEFAULT_CHAIN_ID } from "@constants/environment.constant"; import { useGetTokenBalancesFromChain } from "@query/address"; +import { useSocialWalletContext } from "@hooks/common/use-social-wallet-context"; +import { SocialLoginType } from "src/types/wallet.types"; const balanceQueryKey = ["token-balance", "ugnot"]; @@ -20,6 +28,7 @@ export const useWallet = () => { const [walletAccount, setWalletAccount] = useAtom(WalletState.account); const [, setNetwork] = useAtom(CommonState.network); const [loadingConnect, setLoadingConnect] = useAtom(WalletState.loadingConnect); + const { connectSocialWalletClient } = useSocialWalletContext(); const queryClient = useQueryClient(); const connected = useMemo(() => { @@ -98,19 +107,34 @@ export const useWallet = () => { sessionStorage.removeItem(GNOSWAP_SESSION_ID_KEY); sessionStorage.removeItem(ACCOUNT_SESSION_INFO_KEY); sessionStorage.removeItem(GNOWSWAP_CONNECTED_KEY); + sessionStorage.removeItem(GNOSWAP_WALLET_TYPE_KEY); + sessionStorage.removeItem(GNOSWAP_SOCIAL_LOGIN_TYPE_KEY); accountRepository.setConnectedWallet(false); setLoadingConnect("initial"); }, [accountRepository]); async function initSession() { try { - const adena = AdenaClient.createAdenaClient(); - const data = await adena?.getAccount(); - if (data?.status === "failure") { - disconnectWallet(); + const savedAccount = sessionStorage.getItem(ACCOUNT_SESSION_INFO_KEY); + const savedWalletType = sessionStorage.getItem(GNOSWAP_WALLET_TYPE_KEY); + const savedSocialLoginType = sessionStorage.getItem(GNOSWAP_SOCIAL_LOGIN_TYPE_KEY); + + if (!savedAccount || !savedWalletType) return; + + if (savedWalletType === "SOCIAL_WALLET" && savedSocialLoginType) { + await connectSocialWalletClient(savedSocialLoginType as SocialLoginType); return; } + if (savedWalletType === "ADENA") { + const adena = AdenaClient.createAdenaClient(); + const data = await adena?.getAccount(); + if (data?.status === "failure") { + disconnectWallet(); + return; + } + } + if (walletClient === null) { connectAdenaClient(); } @@ -141,6 +165,7 @@ export const useWallet = () => { } const adena = AdenaClient.createAdenaClient(); if (adena !== null) { + sessionStorage.setItem(GNOSWAP_WALLET_TYPE_KEY, "ADENA"); adena.initAdena(); } else { window.open("https://adena.app/", "", "noopener,noreferrer"); @@ -168,6 +193,7 @@ export const useWallet = () => { if (established.code === 0 || established.code === 4001) { const account = await accountRepository.getAccount(); sessionStorage.setItem(ACCOUNT_SESSION_INFO_KEY, JSON.stringify(account)); + sessionStorage.setItem(GNOSWAP_WALLET_TYPE_KEY, "ADENA"); const availNetwork = SUPPORT_CHAIN_IDS.includes(account.chainId); if (!availNetwork) { switchNetwork(); diff --git a/packages/web/src/providers/social-wallet-provider/SocialWalletProvider.tsx b/packages/web/src/providers/social-wallet-provider/SocialWalletProvider.tsx index f356620dc..b4ce77d48 100644 --- a/packages/web/src/providers/social-wallet-provider/SocialWalletProvider.tsx +++ b/packages/web/src/providers/social-wallet-provider/SocialWalletProvider.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback } from "react"; import { AdenaSDK, GnoSocialWalletProvider } from "@adena-wallet/sdk"; import { SocialWalletLoginType } from "./types"; @@ -13,9 +13,10 @@ import { } from "@constants/environment.constant"; import { useGnoswapContext } from "@hooks/common/use-gnoswap-context"; import { useAtom } from "jotai"; -import { WalletState } from "@states/index"; +import { CommonState, WalletState } from "@states/index"; import { SocialWalletClient } from "@common/clients/wallet-client/social/social-wallet-client"; -import { ACCOUNT_SESSION_INFO_KEY } from "@states/common"; +import { ACCOUNT_SESSION_INFO_KEY, GNOSWAP_SOCIAL_LOGIN_TYPE_KEY, GNOSWAP_WALLET_TYPE_KEY } from "@states/common"; +import { SocialLoginType } from "src/types/wallet.types"; interface SocialWalletConfig { chainId: string; @@ -35,6 +36,7 @@ interface SocialWalletContextType { connect: (type: SocialWalletLoginType) => Promise; disconnect: () => Promise; error: string | null; + connectSocialWalletClient: (loginType: SocialLoginType) => Promise; } export const SocialWalletContext = React.createContext(null); @@ -77,6 +79,7 @@ export const SocialWalletProvider = ({ children }: { children: React.ReactNode } const [connectingState, setConnectingState] = React.useState<"initial" | "loading" | "error" | "done" | "">( "initial", ); + const [sessionId] = useAtom(CommonState.sessionId); const [error, setError] = React.useState(null); const [, setWalletClient] = useAtom(WalletState.client); const [, setWalletAccount] = useAtom(WalletState.account); @@ -108,6 +111,22 @@ export const SocialWalletProvider = ({ children }: { children: React.ReactNode } // [loadingConnect], // ); + const connectSocialWalletClient = useCallback( + async (loginType: SocialLoginType) => { + if (connectingState !== "initial") { + setConnectingState("loading"); + } + const socialWallet = await SocialWalletClient.createSocialWalletClient(loginType); + if (socialWallet !== null) { + sessionStorage.setItem(GNOSWAP_WALLET_TYPE_KEY, "SOCIAL_WALLET"); + sessionStorage.setItem(GNOSWAP_SOCIAL_LOGIN_TYPE_KEY, loginType); + socialWallet.initSocialWallet(loginType); + } + setWalletClient(socialWallet); + }, + [sessionId, connectingState], + ); + const connect = React.useCallback( async (type: SocialWalletLoginType) => { try { @@ -119,6 +138,8 @@ export const SocialWalletProvider = ({ children }: { children: React.ReactNode } throw new Error("Failed to create socail wallet client"); } + sessionStorage.setItem(GNOSWAP_WALLET_TYPE_KEY, "SOCIAL_WALLET"); + sessionStorage.setItem(GNOSWAP_SOCIAL_LOGIN_TYPE_KEY, type); setWalletClient(socialWalletClient); accountRepository.setWalletClient(socialWalletClient); @@ -156,6 +177,7 @@ export const SocialWalletProvider = ({ children }: { children: React.ReactNode } }, 1000); } } catch (err) { + sessionStorage.removeItem(GNOSWAP_WALLET_TYPE_KEY); setConnectingState("error"); setError(err instanceof Error ? err.message : "Failed to connect Social Wallet"); } @@ -176,7 +198,9 @@ export const SocialWalletProvider = ({ children }: { children: React.ReactNode } }, [sdk]); return ( - + {children} ); diff --git a/packages/web/src/states/common.ts b/packages/web/src/states/common.ts index b9e8b7186..2aedfc3e0 100644 --- a/packages/web/src/states/common.ts +++ b/packages/web/src/states/common.ts @@ -45,6 +45,8 @@ export const transactionModalData = atom<{ export const GNOSWAP_SESSION_ID_KEY = "session_id"; export const ACCOUNT_SESSION_INFO_KEY = "account_info"; export const GNOWSWAP_CONNECTED_KEY = "connected-wallet"; +export const GNOSWAP_WALLET_TYPE_KEY = "gnoswap-wallet-type"; +export const GNOSWAP_SOCIAL_LOGIN_TYPE_KEY = "gnoswap-social-login-type"; export const sessionId = atom(""); diff --git a/packages/web/src/utils/transaction-utils.ts b/packages/web/src/utils/transaction-utils.ts new file mode 100644 index 000000000..2cfab164a --- /dev/null +++ b/packages/web/src/utils/transaction-utils.ts @@ -0,0 +1,23 @@ +import { WalletTypeState } from "src/types/wallet.types"; + +type TransactionFunction = (...args: []) => Promise; + +export const withTransactionHandler = + (walletType: WalletTypeState, transactionFn: TransactionFunction) => + async (...args: Parameters) => { + if (walletType.type === "SOCIAL_WALLET") { + // const { openSocialTransactionModal, closeSocialTransactionModal } = useSocialWalletConnectingModal(); + // try { + // openSocialTransactionModal(); + // const result = await transactionFn(...args); + // closeSocialTransactionModal(); + // return result; + // } catch (error) { + // closeSocialTransactionModal(); + // throw error; + // } + } + + // Adena Wallet Transaction + return transactionFn(...args); + };