我正在使用MetaMask向我的DApp合约发送交易。当用户点击注销按钮时,我需要帮助解决如何断开MetaMask账户与我的DApp的链接。
前端:ReactJS
后端:Web3js,Solidity(以太坊)
一旦一个钱包连接成功,用户需要自行断开连接,你对MetaMask没有控制权。实际上,通过检查是否可以访问他们的账户来模拟登录和退出的概念。
const {ethereum} = window;
const accounts = await ethereum.request({method: 'eth_accounts'});
if (accounts && accounts.length > 0) {
console.log("user is connected");
} else {
console.log("user not connected");
}
我做的一件事是注意任何账户变化:
window.ethereum.on('accountsChanged', async () => {
// Do something
});
通常在我的应用程序中,我有一个初始化函数来检查Metamask是否安装?是否已连接?然后我存储状态,以便应用程序可以持久存在,即使在页面刷新时用户似乎已经登录。如果发生任何事情,例如帐户更改或断开连接,则会运行上述脚本并再次运行初始化脚本以重置状态。
// Runs on page load
initialise();
// Runs whenever the user changes account state
window.ethereum.on('accountsChanged', async () => {
initialise();
});
所以,就我所知,目前没有办法联系用户并断开连接,这并没有真正回答你的问题。
let connected = false;
let installed = false;
function isMetaMaskInstalled() {
return Boolean(window.ethereum && window.ethereum.isMetaMask);
}
async function isMetaMaskConnected() {
const {ethereum} = window;
const accounts = await ethereum.request({method: 'eth_accounts'});
return accounts && accounts.length > 0;
}
async function initialise() {
connected = await isMetaMaskConnected();
installed = isMetaMaskInstalled();
}
initialise();
window.ethereum.on('accountsChanged', async () => {
initialise();
});
然后我让我的UI对installed
和connected
变量做出反应。
有一个不错的框架https://usedapp.io/,可用于在TypeScript中设置前端与智能合约的交互。您只需使用其提供程序包装顶级组件即可:
import { Mainnet,ChainId} from "@usedapp/core";
function MyApp({ Component, pageProps }: AppProps) {
return (
<DAppProvider
config={{
supportedChains: [ChainId.Kovan, ChainId.Rinkeby],
}}
>
<Component {...pageProps} />
</DAppProvider>
);
}
接下来编写一个Header组件:
import { useEthers } from "@usedapp/core";
export const Header = () => {
const { account, activateBrowserWallet, deactivate } = useEthers();
const isConnected = account !== undefined;
return (
<div >
{isConnected ? (
<Button onClick={deactivate}>
Disconnect
</Button>
) : (
<Button onClick={() => activateBrowserWallet()}>
Connect
</Button>
)}
</div> );};
请注意,这不会锁定 Metamask,它只是将您的应用程序与该帐户断开连接。
我不知道你是否还存在这个问题,但在async函数内部,你可以调用clearCachedProvider。web3Modal变量被转换为我的web3实例化,例如const web3Modal = new Web3Modal...
await web3Modal.clearCachedProvider()
以上问题可以通过使用wagmi来解决。您只需要将disconnect与其他所需的软件包一起导入到您的项目中即可。
import {
useAccount,
useConnect,
useDisconnect,
useNetwork,
useSignMessage
} from "wagmi";
React:
const { disconnect } = useDisconnect();
const disconnectWallet = async () => {
disconnect();
refreshState();
};
<HStack>
{!activeConnector ? (
<Button onClick={connectWallet}>Connect Wallet</Button>
) : (
<Button onClick={disconnectWallet}>Disconnect</Button>
)}
</HStack>