179 lines
6.5 KiB
TypeScript
179 lines
6.5 KiB
TypeScript
'use client';
|
|
|
|
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 } from '@solana/wallet-adapter-phantom';
|
|
import { clusterApiUrl } from '@solana/web3.js';
|
|
import { useMemo, useEffect } from 'react';
|
|
|
|
// Import wallet adapter CSS
|
|
import '@solana/wallet-adapter-react-ui/styles.css';
|
|
|
|
interface WalletProviderProps {
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export default function WalletProvider({ children }: WalletProviderProps) {
|
|
// The network can be set to 'devnet', 'testnet', or 'mainnet-beta'.
|
|
const network = WalletAdapterNetwork.Devnet;
|
|
|
|
// You can also provide a custom RPC endpoint.
|
|
const endpoint = useMemo(() => clusterApiUrl(network), [network]);
|
|
|
|
const wallets = useMemo(
|
|
() => {
|
|
// 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 (
|
|
<ConnectionProvider endpoint={endpoint}>
|
|
<SolanaWalletProvider
|
|
wallets={wallets}
|
|
autoConnect={false} // Disable autoConnect on mobile to prevent "not ready" errors
|
|
onError={(error) => {
|
|
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');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}}
|
|
>
|
|
<WalletModalProvider>
|
|
{children}
|
|
</WalletModalProvider>
|
|
</SolanaWalletProvider>
|
|
</ConnectionProvider>
|
|
);
|
|
}
|