From 36d28d89db7501be521e2fd4b1111880ef131462 Mon Sep 17 00:00:00 2001 From: Sewmina Date: Mon, 18 Aug 2025 22:13:57 +0530 Subject: [PATCH] mobile wallet attempt --- app/components/Header.tsx | 509 +++++++++++++++++------------- app/components/WalletProvider.tsx | 152 +++++++-- package.json | 2 +- 3 files changed, 427 insertions(+), 236 deletions(-) diff --git a/app/components/Header.tsx b/app/components/Header.tsx index cee20ac..389f637 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useImperativeHandle, forwardRef } from 'react'; import { useWallet } from '@solana/wallet-adapter-react'; -import { WalletName } from '@solana/wallet-adapter-base'; +import { WalletMultiButton } from '@solana/wallet-adapter-react-ui'; import { Connection, PublicKey } from '@solana/web3.js'; import Image from 'next/image'; import '@solana/wallet-adapter-react-ui/styles.css'; @@ -13,92 +13,38 @@ export interface HeaderRef { refreshBalance: () => Promise; } -// Custom Wallet Button Component -const CustomWalletButton = () => { - const { publicKey, disconnect, select, wallets } = useWallet(); - const [isDropdownOpen, setIsDropdownOpen] = useState(false); - - const handleWalletSelect = (walletName: WalletName) => { - select(walletName); - setIsDropdownOpen(false); - }; - - const handleDisconnect = () => { - disconnect(); - setIsDropdownOpen(false); - }; - - if (publicKey) { - return ( -
- - - {isDropdownOpen && ( -
- -
- )} -
- ); - } - - return ( -
- - - {isDropdownOpen && ( -
- {wallets.map((wallet) => ( - - ))} -
- )} -
- ); -}; - const Header = forwardRef((props, ref) => { const { publicKey } = useWallet(); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const [isScrolled, setIsScrolled] = useState(false); const [dinoBalance, setDinoBalance] = useState(null); const [isLoadingBalance, setIsLoadingBalance] = useState(false); + const [showMobileWalletHelp, setShowMobileWalletHelp] = useState(false); + const [mobileWalletReady, setMobileWalletReady] = useState(false); + + // Check if we're on mobile + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + typeof window !== 'undefined' ? navigator.userAgent : '' + ); + + // Custom styling for WalletMultiButton + const walletButtonStyle = { + backgroundColor: 'transparent', + border: 'none', + borderRadius: '12px', + padding: '8px 16px', + fontSize: '14px', + fontWeight: '600', + transition: 'all 0.3s ease', + boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)', + }; + + // Mobile-specific wallet button styling + const mobileWalletButtonStyle = { + ...walletButtonStyle, + fontSize: '12px', + padding: '6px 12px', + }; const fetchDinoBalance = async () => { if (!publicKey) { @@ -149,6 +95,48 @@ const Header = forwardRef((props, ref) => { fetchDinoBalance(); }, [publicKey]); + // Check mobile wallet readiness + useEffect(() => { + if (isMobile && typeof window !== 'undefined') { + const checkWalletReadiness = () => { + const phantom = (window as { phantom?: { solana?: { isConnected?: boolean } } }).phantom; + if (phantom && phantom.solana) { + console.log('Mobile Phantom wallet is ready'); + setMobileWalletReady(true); + } else { + console.log('Mobile Phantom wallet not ready yet'); + setMobileWalletReady(false); + } + }; + + // Check immediately + checkWalletReadiness(); + + // Check periodically + const interval = setInterval(checkWalletReadiness, 2000); + + // Check when page becomes visible/focused + const handleVisibilityChange = () => { + if (!document.hidden) { + checkWalletReadiness(); + } + }; + + const handleFocus = () => { + checkWalletReadiness(); + }; + + document.addEventListener('visibilitychange', handleVisibilityChange); + window.addEventListener('focus', handleFocus); + + return () => { + clearInterval(interval); + document.removeEventListener('visibilitychange', handleVisibilityChange); + window.removeEventListener('focus', handleFocus); + }; + } + }, [isMobile]); + const handleBuyDino = () => { // Redirect to DexScreener - you can update this URL to the actual $DINO token page window.open('https://dexscreener.com/solana', '_blank'); @@ -162,152 +150,56 @@ const Header = forwardRef((props, ref) => { }; return ( -
-
-
- {/* Logo and Title */} -
-
-
- DINO Token Icon -
-

- DINO -

-
-
- - {/* Desktop Navigation Links */} - - - {/* Buy $DINO Button and Wallet Connect - Desktop */} -
- - - {publicKey ? ( -
- {/* DINO Balance Display */} -
-
-
- - {isLoadingBalance ? ( -
-
- Loading... -
- ) : ( - `${formatBalance(dinoBalance)} $DINO` - )} -
-
+ <> +
+
+
+ {/* Logo and Title */} +
+
+
+ DINO Token Icon
- - +

+ DINO +

- ) : ( - - )} -
+
- {/* Mobile Menu Button */} -
- - -
-
- - {/* Mobile Menu */} - {isMobileMenuOpen && ( -
-
+ {/* Desktop Navigation Links */} + + + {/* Buy $DINO Button and Wallet Connect - Desktop */} +
+ + + {publicKey ? ( +
+ {/* DINO Balance Display */} +
@@ -339,13 +246,181 @@ const Header = forwardRef((props, ref) => {
+ +
+ ) : ( + )}
+ + {/* Mobile Menu Button */} +
+ + + {/* Mobile wallet help message */} + {!publicKey && ( +
+ Tap to connect your wallet +
+ )} + + {/* Mobile wallet readiness indicator */} + {isMobile && !publicKey && ( +
+
+ + {mobileWalletReady ? 'Wallet Ready' : 'Checking Wallet...'} + +
+ )} + + {/* Mobile wallet help button */} + {isMobile && !publicKey && ( + + )} + + +
+ + {/* Mobile Menu */} + {isMobileMenuOpen && ( +
+
+ + Support + + + Whitepaper + +
+ Socials: + + + + + + + + + + +
+ {publicKey && ( +
+
+
+
+ + {isLoadingBalance ? ( +
+
+ Loading... +
+ ) : ( + `${formatBalance(dinoBalance)} $DINO` + )} +
+
+
+
+ )} +
+
+ )}
- )} -
-
+
+
+ + {/* Mobile Wallet Help Modal */} + {showMobileWalletHelp && ( +
+
+
+

Mobile Wallet Help

+ +
+ +
+
+

If you get "Wallet not ready" error:

+
    +
  1. Install Phantom from App Store (iOS) or Play Store (Android)
  2. +
  3. Open the Phantom app and create/import a wallet
  4. +
  5. Return to this page and refresh
  6. +
  7. Try connecting again
  8. +
+
+ + + +
+ Make sure your wallet app is open before connecting +
+
+
+
+ )} + ); }); diff --git a/app/components/WalletProvider.tsx b/app/components/WalletProvider.tsx index ba738dc..e0d6227 100644 --- a/app/components/WalletProvider.tsx +++ b/app/components/WalletProvider.tsx @@ -3,16 +3,9 @@ import { WalletAdapterNetwork } from '@solana/wallet-adapter-base'; import { ConnectionProvider, WalletProvider as SolanaWalletProvider } from '@solana/wallet-adapter-react'; import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'; -import { - PhantomWalletAdapter, - SolflareWalletAdapter, - AlphaWalletAdapter, - BitKeepWalletAdapter, - BitpieWalletAdapter, - CloverWalletAdapter -} from '@solana/wallet-adapter-wallets'; +import { PhantomWalletAdapter } from '@solana/wallet-adapter-phantom'; import { clusterApiUrl } from '@solana/web3.js'; -import { useMemo } from 'react'; +import { useMemo, useEffect } from 'react'; // Import wallet adapter CSS import '@solana/wallet-adapter-react-ui/styles.css'; @@ -29,28 +22,151 @@ export default function WalletProvider({ children }: WalletProviderProps) { const endpoint = useMemo(() => clusterApiUrl(network), [network]); const wallets = useMemo( - () => [ - new PhantomWalletAdapter(), - new SolflareWalletAdapter(), - new AlphaWalletAdapter(), - new BitKeepWalletAdapter(), - new BitpieWalletAdapter(), - new CloverWalletAdapter(), - ], + () => { + // Check if we're on mobile + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + typeof window !== 'undefined' ? navigator.userAgent : '' + ); + + if (isMobile) { + console.log('Mobile device detected - configuring mobile-optimized wallets'); + + // Mobile-optimized wallet configuration - focus on Phantom which has the best mobile support + return [ + new PhantomWalletAdapter({ + // Mobile-specific options for better compatibility + appIdentity: { + name: 'DINO Game', + uri: window.location.origin, + icon: `${window.location.origin}/dino_icon.jpg` + } + }) + ]; + } else { + console.log('Desktop device detected - configuring standard wallets'); + + // Standard desktop wallet configuration + return [ + new PhantomWalletAdapter() + ]; + } + }, [] ); + // Mobile wallet detection and setup + useEffect(() => { + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + typeof window !== 'undefined' ? navigator.userAgent : '' + ); + + if (isMobile) { + console.log('Mobile wallet setup initiated'); + + // Check for installed mobile wallets + if (typeof window !== 'undefined') { + // Wait for wallet objects to be available + const checkWallets = () => { + if ('phantom' in window) { + console.log('Phantom wallet detected on mobile'); + + // Check if Phantom is actually ready + const phantom = (window as { phantom?: { solana?: { isConnected?: boolean } } }).phantom; + if (phantom && phantom.solana) { + console.log('Phantom Solana provider is ready'); + + // Check if wallet is connected + if (phantom.solana.isConnected) { + console.log('Phantom wallet is already connected'); + } else { + console.log('Phantom wallet is available but not connected'); + } + } else { + console.log('Phantom Solana provider not ready yet'); + } + } else { + console.log('No Phantom wallet detected - user may need to install it'); + } + }; + + // Check immediately + checkWallets(); + + // Check again after a short delay to catch late-loading wallets + setTimeout(checkWallets, 1000); + + // Check when window becomes visible (user returns to app) + const handleVisibilityChange = () => { + if (!document.hidden) { + console.log('App became visible, checking wallets...'); + checkWallets(); + } + }; + + document.addEventListener('visibilitychange', handleVisibilityChange); + + // Also check when the page becomes focused + const handleFocus = () => { + console.log('Page focused, checking wallets...'); + checkWallets(); + }; + + window.addEventListener('focus', handleFocus); + + return () => { + document.removeEventListener('visibilitychange', handleVisibilityChange); + window.removeEventListener('focus', handleFocus); + }; + } + } + }, []); + return ( { console.error('Wallet adapter error:', error); + // Handle mobile-specific wallet errors if (error.message.includes('signature verification failed')) { console.warn('Mobile wallet signature verification issue detected'); } + + // Handle mobile connection issues + if (error.message.includes('User rejected')) { + console.warn('User rejected wallet connection'); + } + + // Handle deep linking issues on mobile + if (error.message.includes('deep link') || error.message.includes('redirect')) { + console.warn('Mobile deep linking issue detected'); + } + + // Handle "wallet not ready" errors + if (error.message.includes('not ready') || error.message.includes('not installed')) { + console.warn('Mobile wallet not ready/installed - providing guidance'); + + // Show helpful message to user + if (typeof window !== 'undefined') { + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + if (isMobile) { + // On mobile, we can provide app store links + console.log('Mobile wallet not ready - user may need to install wallet app'); + + // Check if Phantom is actually available + const phantom = (window as { phantom?: { solana?: { isConnected?: boolean } } }).phantom; + if (!phantom) { + console.log('Phantom not detected - user needs to install the app'); + } else if (!phantom.solana) { + console.log('Phantom detected but Solana provider not ready'); + } else { + console.log('Phantom Solana provider is ready'); + } + } + } + } }} > diff --git a/package.json b/package.json index 75e3366..cf1a3a9 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev --turbopack", + "dev": "next dev --turbopack -p 80", "build": "next build", "start": "next start -p 8170", "lint": "next lint"