@@ -10,7 +10,7 @@ import {
1010} from "@/components/ui/dropdown-menu" ;
1111import { useWallet , useWalletList , useNetwork , useAssets } from "@meshsdk/react" ;
1212import { useSiteStore } from "@/lib/zustand/site" ;
13- import { useEffect } from "react" ;
13+ import { useEffect , useRef } from "react" ;
1414import useUser from "@/hooks/useUser" ;
1515import { useUserStore } from "@/lib/zustand/user" ;
1616import { getProvider } from "@/utils/get-provider" ;
@@ -30,12 +30,86 @@ export default function ConnectWallet() {
3030 const networkId = useNetwork ( ) ;
3131 const assets = useAssets ( ) ;
3232 const network = useSiteStore ( ( state ) => state . network ) ;
33+ const retryTimeoutRef = useRef < NodeJS . Timeout | null > ( null ) ;
34+ const retryCountRef = useRef ( 0 ) ;
35+ const walletsRef = useRef ( wallets ) ;
36+
37+ // Keep wallets ref in sync
38+ useEffect ( ( ) => {
39+ walletsRef . current = wallets ;
40+ } , [ wallets ] ) ;
3341
3442 async function connectWallet ( walletId : string ) {
3543 setPastWallet ( walletId ) ;
3644 await connect ( walletId ) ;
3745 }
3846
47+ // Retry wallet detection on mount to handle cached loads
48+ // Browser extensions inject wallets asynchronously, and cached scripts may load
49+ // before MeshProvider/wallet detection is fully initialized
50+ useEffect ( ( ) => {
51+ // If wallets are already detected, no need to retry
52+ if ( wallets . length > 0 ) {
53+ retryCountRef . current = 0 ;
54+ if ( retryTimeoutRef . current ) {
55+ clearTimeout ( retryTimeoutRef . current ) ;
56+ retryTimeoutRef . current = null ;
57+ }
58+ return ;
59+ }
60+
61+ // Clear any existing timeout
62+ if ( retryTimeoutRef . current ) {
63+ clearTimeout ( retryTimeoutRef . current ) ;
64+ retryTimeoutRef . current = null ;
65+ }
66+
67+ // Reset retry count
68+ retryCountRef . current = 0 ;
69+
70+ // Retry detection with increasing delays: immediate, 100ms, 500ms, 1000ms
71+ // This gives MeshProvider and browser extensions time to initialize
72+ const delays = [ 0 , 100 , 500 , 1000 ] ;
73+ const maxRetries = delays . length ;
74+
75+ const checkWallets = ( ) => {
76+ // Check current wallets (using ref to avoid closure issues)
77+ if ( walletsRef . current . length > 0 ) {
78+ retryCountRef . current = 0 ;
79+ if ( retryTimeoutRef . current ) {
80+ clearTimeout ( retryTimeoutRef . current ) ;
81+ retryTimeoutRef . current = null ;
82+ }
83+ return ;
84+ }
85+
86+ // If we've reached max retries, stop
87+ if ( retryCountRef . current >= maxRetries ) {
88+ retryCountRef . current = 0 ;
89+ return ;
90+ }
91+
92+ // Schedule next retry
93+ const delay = delays [ retryCountRef . current ] ;
94+ retryCountRef . current ++ ;
95+
96+ // Use setTimeout even for 0ms delay to avoid recursion issues
97+ retryTimeoutRef . current = setTimeout ( checkWallets , delay ) ;
98+ } ;
99+
100+ // Start checking immediately (using setTimeout with 0ms for next tick)
101+ retryTimeoutRef . current = setTimeout ( checkWallets , 0 ) ;
102+ retryCountRef . current = 1 ;
103+
104+ return ( ) => {
105+ if ( retryTimeoutRef . current ) {
106+ clearTimeout ( retryTimeoutRef . current ) ;
107+ retryTimeoutRef . current = null ;
108+ }
109+ retryCountRef . current = 0 ;
110+ } ;
111+ } , [ wallets . length ] ) ;
112+
39113 // Auto-connect if user had connected before
40114 useEffect ( ( ) => {
41115 if ( pastWallet && ! connected && wallets . length > 0 ) {
0 commit comments