Angular中使用Web3Modal v2实现MetaMask消息签名及连接监听
Web3Modal v2 连接状态监听、Provider获取及消息签名实现方案
问题背景
升级至WalletConnect v2后,Web3Modal v2不再提供v1中的await web3Modal.connect()方法,无法直接通过该方法感知用户连接完成,同时需要实现消息签名、Provider获取等原有功能。
v1实现代码:
this.web3Modal.clearCachedProvider(); this.provider = await this.web3Modal.connect(); // set provider this.web3js = new Web3(this.provider); // create web3 instance this.accounts = await this.web3js.eth.getAccounts(); const signedMessage = await this.web3js.eth.personal.sign('You are login into gamers passport, This action will not cost you any transaction fee.', address);
当前v2初始化代码:
import { EthereumClient, w3mConnectors, w3mProvider } from '@web3modal/ethereum' import { Web3Modal } from '@web3modal/html' import { configureChains, createConfig, getAccount } from '@wagmi/core'; import { arbitrum, mainnet, polygon } from '@wagmi/core/chains'; const chains = [arbitrum, mainnet, polygon] const projectId = 'my project id' const { publicClient } = configureChains(chains, [w3mProvider({ projectId })]) const wagmiConfig = createConfig({ autoConnect: true, connectors: w3mConnectors({ projectId, chains }), publicClient }) const ethereumClient = new EthereumClient(wagmiConfig, chains) this.web3Modal = new Web3Modal({ projectId, themeVariables: {'--w3m-z-index': '1100'} }, ethereumClient) // 自定义按钮触发 this.web3Modal.openModal();
解决方案
1. 监听用户连接状态
Web3Modal v2基于Wagmi实现,可通过Wagmi的watchAccount方法监听连接状态变化,替代v1中connect()的回调逻辑:
import { watchAccount } from '@wagmi/core'; // 在初始化代码后添加监听 watchAccount((account) => { if (account.isConnected) { // 用户已完成连接,在此处执行后续逻辑(如获取Provider、签名) console.log('用户已连接,地址:', account.address); this.handleConnected(account.address); } else { // 用户断开连接 console.log('用户已断开连接'); } });
2. 获取Provider与账户信息
连接完成后,可通过Wagmi的getConnectorClient获取Provider,结合Web3.js实例化:
import { getConnectorClient } from '@wagmi/core'; import Web3 from 'web3'; async handleConnected(address) { // 获取Provider const client = await getConnectorClient(); this.provider = client; this.web3js = new Web3(this.provider); // 获取账户列表(也可直接从watchAccount的account参数中取address) this.accounts = await this.web3js.eth.getAccounts(); }
3. 实现消息签名
有两种方式实现签名:
- 方式一:沿用Web3.js的
personal.sign(与v1逻辑一致)
async signMessage(address) { const signedMessage = await this.web3js.eth.personal.sign( 'You are login into gamers passport, This action will not cost you any transaction fee.', address ); console.log('签名结果:', signedMessage); }
- 方式二:使用Wagmi内置的
signMessage方法(更贴合v2生态)
import { signMessage } from '@wagmi/core'; async signMessage(address) { const result = await signMessage({ message: 'You are login into gamers passport, This action will not cost you any transaction fee.', account: address, }); console.log('签名结果:', result); }
内容的提问来源于stack exchange,提问作者It's Bender
相关产品推荐
相关产品推荐

