如何为web3.js设置AppKit(Web3Modal)的Provider?
如何为web3.js设置AppKit(Web3Modal)的Provider?
嘿,这个问题我用AppKit的时候也碰到过!你说得对,window.ethereum只能适配MetaMask,没法兼容AppModal里选的其他钱包。不过好在AppKit用WagmiAdapter来统一管理所有钱包连接,我们可以直接从Wagmi的核心工具里拿到通用的EIP-1193 Provider,完美适配任何用户选中的钱包。
下面是修改后的完整代码,我会标注关键的改动点:
import { createAppKit, ReownAppKitModal } from '@reown/appkit'; import { bsc } from '@reown/appkit/networks'; import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'; import { reconnect, watchAccount, getAccount, getWalletClient } from '@wagmi/core'; import { Web3 } from 'web3'; const projectId = '...'; const networkList = [bsc]; const wagmiAdapter = new WagmiAdapter({ projectId, networks: networkList }); const metadata = { name: '...', description: '...', url: 'https://...', icons: ['...'], }; const modal = createAppKit({ adapters: [wagmiAdapter], networks: networkList, projectId, metadata: metadata, themeMode: 'light' }); // 初始化Web3实例的变量,方便全局使用 let web3; // 定义初始化Web3的函数 async function initWeb3FromWallet() { const account = await getAccount(wagmiAdapter.wagmiConfig); if (account.isConnected) { // 通过Wagmi获取当前连接的钱包客户端 const walletClient = await getWalletClient(wagmiAdapter.wagmiConfig); // 从客户端中提取符合EIP-1193标准的Provider const provider = walletClient?.transport?.provider; if (provider) { web3 = new Web3(provider); console.log('Web3已适配当前选中的钱包:', account.address); // 这里可以继续编写你的合约交互逻辑 } } } // 监听账户连接/切换事件,确保Web3实例始终和当前钱包同步 watchAccount({ onChange: async () => { await initWeb3FromWallet(); } }); // 初始重连后检查是否已有保存的连接,自动初始化Web3 reconnect(wagmiAdapter.wagmiConfig).then(async () => { await initWeb3FromWallet(); });
关键逻辑解释:
getWalletClient:Wagmi的核心方法,能拿到当前用户选中钱包的客户端实例,不管是MetaMask、Trust Wallet还是其他AppKit支持的钱包,它都会返回统一格式的对象。walletClient.transport.provider:从客户端中提取的标准Provider,完全符合EIP-1193规范,替代了window.ethereum的局限性,适配所有合规钱包。watchAccount:监听账户的连接、切换、断开等状态变化,用户切换钱包时Web3实例会自动更新,始终和当前选中的钱包保持同步。- 初始重连检查:调用
reconnect后立即检查是否有历史连接,自动初始化Web3,避免用户重复操作,提升体验。
这样修改后,不管用户在AppKit弹窗里选了哪款钱包,Web3.js都能无缝对接,再也不用依赖特定钱包的全局变量啦!
备注:内容来源于stack exchange,提问作者Alireza Zojaji
相关产品推荐
相关产品推荐

