fixed wallet button connection and disconnection

This commit is contained in:
ayomaska18
2024-10-26 22:53:26 +01:00
parent c6ac46f227
commit d683916c16
3 changed files with 88 additions and 79 deletions

View File

@@ -1,102 +1,114 @@
'use client'; 'use client';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useSDK, MetaMaskProvider } from '@metamask/sdk-react';
import { Button } from '@/components/ui/button';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
function WalletIcon(props: React.SVGProps<SVGSVGElement>) { declare global {
return ( interface Window {
<svg ethereum?: {
{...props} isMetaMask?: boolean;
xmlns="http://www.w3.org/2000/svg" request: (request: {
width="24" method: string;
height="24" params?: Array<unknown>; // Use `unknown` instead of `any`
viewBox="0 0 24 24" }) => Promise<unknown>; // Specify a more accurate return type if possible
fill="none" };
stroke="currentColor" }
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M21 12V7H5a2 2 0 0 1 0-4h14v4" />
<path d="M3 5v14a2 2 0 0 0 2 2h16v-5" />
<path d="M18 12a2 2 0 0 0 0 4h4v-4Z" />
</svg>
);
}
function formatAddress(address: string | undefined): string {
if (!address) return '';
return `${address.slice(0, 6)}...${address.slice(-4)}`;
} }
function MetaMaskConnect() { function MetaMaskConnect() {
const { sdk, connected, connecting, account } = useSDK(); const [isConnected, setIsConnected] = useState<boolean>(false);
const [isConnected, setIsConnected] = useState(false); const [account, setAccount] = useState<string | null>(null);
// Initial check on load
useEffect(() => { useEffect(() => {
setIsConnected(connected); const checkConnection = async () => {
}, [connected]); if (typeof window !== 'undefined' && window.ethereum) {
const connect = async () => {
try { try {
await sdk?.connect(); // Check if there are any accounts already connected
const accounts = (await window.ethereum.request({
method: 'eth_accounts',
})) as string[];
if (accounts && accounts.length > 0) {
setIsConnected(true); setIsConnected(true);
} catch (err) { setAccount(accounts[0]);
console.warn(`No accounts found`, err); localStorage.setItem('isConnected', JSON.stringify(true));
localStorage.setItem('account', accounts[0]);
} else {
// No connected accounts found; check `localStorage`
const storedIsConnected = JSON.parse(
localStorage.getItem('isConnected') || 'false'
);
const storedAccount = localStorage.getItem('account') || null;
setIsConnected(storedIsConnected);
setAccount(storedAccount);
}
} catch (error) {
console.error('Error checking MetaMask connection:', error);
}
} }
}; };
const disconnect = () => { checkConnection();
if (sdk) { }, []);
sdk.terminate();
setIsConnected(false); // Update localStorage whenever connection state changes
useEffect(() => {
if (typeof window !== 'undefined') {
localStorage.setItem('isConnected', JSON.stringify(isConnected));
localStorage.setItem('account', account || '');
} }
}, [isConnected, account]);
const connect = async () => {
try {
const accounts = (await window.ethereum?.request({
method: 'eth_requestAccounts',
})) as string[];
if (accounts && accounts.length > 0) {
setIsConnected(true);
setAccount(accounts[0]);
localStorage.setItem('isConnected', JSON.stringify(true));
localStorage.setItem('account', accounts[0]);
}
} catch (error) {
console.error('MetaMask connection failed:', error);
}
};
const disconnect = async () => {
setIsConnected(false);
setAccount(null);
localStorage.setItem('isConnected', JSON.stringify(false));
localStorage.removeItem('account');
await window.ethereum?.request({
method: 'wallet_revokePermissions',
params: [{ eth_accounts: {} }],
});
}; };
return ( return (
<div className="relative"> <div className="relative">
{isConnected ? ( {isConnected ? (
<Popover> <div>
<PopoverTrigger asChild> <button
<Button>{formatAddress(account)}</Button>
</PopoverTrigger>
<PopoverContent className="w-44">
<Button
variant="destructive"
onClick={disconnect} onClick={disconnect}
className="w-full px-4 py-2 text-left hover:bg-muted hover:text-destructive" className="bg-red-500 text-white px-4 py-2 rounded"
> >
Disconnect Disconnect
</Button> </button>
</PopoverContent> <span>
</Popover> {account && `${account.slice(0, 6)}...${account.slice(-4)}`}
</span>
</div>
) : ( ) : (
<Button disabled={connecting} onClick={connect}> <button
<WalletIcon className="mr-2 h-4 w-4" /> Connect Wallet onClick={connect}
</Button> className="bg-blue-500 text-white px-4 py-2 rounded"
>
Connect Wallet
</button>
)} )}
</div> </div>
); );
} }
export default function MetaMaskConnectWrapper() { export default MetaMaskConnect;
return (
<MetaMaskProvider
debug={false}
sdkOptions={{
dappMetadata: {
name: 'My dApp',
url: typeof window !== 'undefined' ? window.location.href : '',
},
}}
>
<MetaMaskConnect />
</MetaMaskProvider>
);
}

View File

@@ -33,7 +33,6 @@ export const buyHandler = async (
return; return;
} }
// @ts-expect-error: window.ethereum might not match ExternalProvider exactly
const provider = new ethers.providers.Web3Provider(window.ethereum); const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner(); const signer = provider.getSigner();
const contract = getContract().connect(signer); const contract = getContract().connect(signer);

2
package-lock.json generated
View File

@@ -13050,7 +13050,6 @@
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz",
"integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==",
"dev": true, "dev": true,
"hasInstallScript": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"node-gyp-build": "^4.3.0" "node-gyp-build": "^4.3.0"
@@ -13413,7 +13412,6 @@
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz",
"integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==",
"dev": true, "dev": true,
"hasInstallScript": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"node-gyp-build": "^4.3.0" "node-gyp-build": "^4.3.0"