@@ -21,32 +21,55 @@ import { ADAPTER_EVENTS } from '@web3auth/base';
2121
2222// LOCAL IMPORTS
2323import { useAuth } from '@src/hooks/use-auth' ;
24- import { ensureAAReady } from '@src/utils/wallet.ts ' ;
24+ import { ensureAAReady } from '@src/utils/wallet' ;
2525import { useWeb3Auth } from '@src/hooks/use-web3-auth' ;
2626import { useGetUserLazyQuery } from '@src/graphql/generated/hooks' ;
2727
2828interface UseAccountSessionHook {
29- login : ( ) => Promise < void > ;
30- logout : ( silent ?: boolean ) => Promise < void > ;
31- syncAddress : ( ) => Promise < void > ;
32- refreshUser : ( ) => Promise < void > ;
33- loading : boolean ;
29+ login : ( ) => Promise < void > ;
30+ logout : ( ) => Promise < void > ;
31+ syncAddress : ( ) => Promise < void > ;
32+ refreshUser : ( ) => Promise < void > ;
33+ loading : boolean ;
34+ userChecked : boolean ;
3435}
3536
3637let listenerAttached = false ;
3738let restoreDone = false ;
3839let loginPerformed = false ;
3940
4041export const useAccountSession = ( ) : UseAccountSessionHook => {
41- const [ bootstrapping , setBootstrapping ] = useState ( true ) ;
42- const [ loginInProgress , setLoginInProgress ] = useState ( false ) ;
42+ const { session , isAuthLoading : reduxLoading } = useAuth ( ) ;
43+ const { web3Auth } = useWeb3Auth ( ) ;
4344 const dispatch = useDispatch ( ) ;
44- const { web3Auth, bundlerClient, smartAccount } = useWeb3Auth ( ) ;
45- const { isAuthLoading : reduxLoading , session } = useAuth ( ) ;
46- const [ loadUser , { data : userData , loading : apiLoading } ] = useGetUserLazyQuery ( { fetchPolicy : 'cache-and-network' } ) ;
47- const lastFetchedAddressRef = useRef < Address | undefined > ( undefined ) ;
48- const userAddressRef = useRef < Address | undefined > ( undefined ) ;
49- const sessionRef = useRef ( session ) ;
45+ const [ loadUser ] = useGetUserLazyQuery ( { fetchPolicy : 'cache-and-network' } ) ;
46+
47+ const [ loginInProgress , setLoginInProgress ] = useState ( false ) ;
48+ const [ verifyingUser , setVerifyingUser ] = useState ( false ) ;
49+ const [ userChecked , setUserChecked ] = useState ( false ) ;
50+
51+ const sessionRef = useRef ( session ) ;
52+ const lastVerifiedRef = useRef < Address | null > ( null ) ;
53+ const loading = loginInProgress || reduxLoading || verifyingUser ;
54+
55+ const mergeSession = ( patch : Partial < ReduxSession > ) => {
56+ const prev = sessionRef . current ;
57+ const derivedAddress = patch . user ?. address as Address | undefined ;
58+
59+ const next : ReduxSession = {
60+ ...prev ,
61+ ...patch ,
62+ address : patch . address ?? prev . address ?? derivedAddress ,
63+ authenticated : Boolean (
64+ ( patch . address ?? prev . address ?? derivedAddress ) &&
65+ ( patch . user ?? prev . user )
66+ ) ,
67+ } ;
68+
69+ if ( JSON . stringify ( prev ) !== JSON . stringify ( next ) ) {
70+ dispatch ( setSession ( { session : next } ) ) ;
71+ }
72+ } ;
5073
5174 const getPrimaryAddress = useCallback ( async ( ) : Promise < Address | undefined > => {
5275 const accs = ( await web3Auth . provider ?. request ( { method : 'eth_accounts' } ) ) as string [ ] | undefined ;
@@ -56,46 +79,55 @@ export const useAccountSession = (): UseAccountSessionHook => {
5679 const clearRedux = ( ) => {
5780 dispatch ( setBalance ( { balance : 0 } ) ) ;
5881 dispatch ( setSession ( { session : defaultSession } ) ) ;
59- userAddressRef . current = undefined ;
60- lastFetchedAddressRef . current = undefined ;
82+ setUserChecked ( false ) ;
6183 loginPerformed = false ;
6284 } ;
6385
64- const mergeSession = ( patch : Partial < ReduxSession > ) => {
65- const prev = sessionRef . current ;
66- const next = { ...prev , ...patch } ;
67- next . authenticated = Boolean ( next . address && next . user ) ;
68-
69- if ( JSON . stringify ( next ) !== JSON . stringify ( prev ) ) {
70- dispatch ( setSession ( { session : next } ) ) ;
71- }
72- } ;
73-
7486 const syncAddress = async ( ) => {
7587 const address = await getPrimaryAddress ( ) ;
76- let { info } = sessionRef . current ;
7788 if ( ! address ) throw new Error ( 'No address found' ) ;
89+ if ( address === lastVerifiedRef . current && userChecked && ! verifyingUser ) return ;
90+
91+ lastVerifiedRef . current = address ;
92+
93+ let { info } = sessionRef . current ;
7894 if ( ! info ) info = await web3Auth . getUserInfo ?.( ) ;
7995
8096 mergeSession ( { address, info } ) ;
81- loadUser ( { variables : { input : { address, idSession : info ?. idToken } } } ) ;
97+ setVerifyingUser ( true ) ;
98+ setUserChecked ( false ) ;
99+
100+ const { data } = await loadUser ( {
101+ variables : { input : { address, idSession : info ?. idToken } } ,
102+ } ) ;
103+ if ( data ?. getUser ) {
104+ dispatch ( setUser ( { user : data . getUser } ) ) ;
105+ mergeSession ( {
106+ user : data . getUser ,
107+ address : data . getUser . address as Address ,
108+ } ) ;
109+ }
110+ setVerifyingUser ( false ) ;
111+ setUserChecked ( true ) ;
82112 } ;
83113
84114 const refreshUser = async ( ) => {
85115 const address = await getPrimaryAddress ( ) ;
86116 if ( ! address ) throw new Error ( 'No address found' ) ;
87- const result = await loadUser ( { variables : { input : { address } } } ) ;
88-
89- dispatch ( setUser ( { user : result . data . getUser } ) ) ;
117+ const { data } = await loadUser ( { variables : { input : { address } } } ) ;
118+ if ( data ?. getUser ) {
119+ dispatch ( setUser ( { user : data . getUser } ) ) ;
120+ mergeSession ( { user : data . getUser } ) ;
121+ }
90122 } ;
91123
92124 const logout = useCallback ( async ( ) => {
93- if ( web3Auth . connected ) await web3Auth . logout ( ) ;
125+ await web3Auth . logout ?. ( ) ;
94126 clearRedux ( ) ;
127+ restoreDone = false ;
95128 } , [ web3Auth ] ) ;
96129
97130 const login = useCallback ( async ( ) => {
98- if ( loginInProgress ) return ;
99131 if ( loginInProgress || loginPerformed ) return ;
100132
101133 setLoginInProgress ( true ) ;
@@ -113,15 +145,9 @@ export const useAccountSession = (): UseAccountSessionHook => {
113145 setLoginInProgress ( false ) ;
114146 dispatch ( setAuthLoading ( { isAuthLoading : false } ) ) ;
115147 }
116- } , [ web3Auth , bundlerClient , smartAccount , loginInProgress ] ) ;
117-
118- useEffect ( ( ) => {
119- sessionRef . current = session ;
120- } , [ session ] ) ;
148+ } , [ web3Auth , loginInProgress ] ) ;
121149
122- useEffect ( ( ) => {
123- userAddressRef . current = session . user ? session . address : undefined ;
124- } , [ session . user , session . address ] ) ;
150+ useEffect ( ( ) => { sessionRef . current = session } , [ session ] ) ;
125151
126152 useEffect ( ( ) => {
127153 if ( ! web3Auth || restoreDone ) return ;
@@ -134,8 +160,6 @@ export const useAccountSession = (): UseAccountSessionHook => {
134160 }
135161 } catch {
136162 await logout ( ) ;
137- } finally {
138- setBootstrapping ( false ) ;
139163 }
140164 } ) ( ) ;
141165 } , [ logout ] ) ;
@@ -152,27 +176,7 @@ export const useAccountSession = (): UseAccountSessionHook => {
152176 web3Auth . off ( ADAPTER_EVENTS . CONNECTED , syncAddress ) ;
153177 listenerAttached = false ;
154178 } ;
155- } , [ logout ] ) ;
156-
157- useEffect ( ( ) => {
158- if ( userData ?. getUser ) {
159- const address = sessionRef . current . address as Address ;
179+ } , [ web3Auth , logout ] ) ;
160180
161- if ( ! address ) { return ; }
162-
163- if ( userAddressRef . current !== address ) {
164- userAddressRef . current = address ;
165- dispatch ( setUser ( { user : userData . getUser } ) ) ;
166- mergeSession ( { user : userData . getUser } ) ;
167- }
168- }
169- } , [ userData ] ) ;
170-
171- return {
172- login,
173- logout,
174- syncAddress,
175- refreshUser,
176- loading : bootstrapping || reduxLoading || apiLoading || loginInProgress ,
177- } ;
181+ return { login, logout, syncAddress, refreshUser, loading, userChecked } ;
178182} ;
0 commit comments