最近花了些時間研究了下 MetaMask 連接無法切換帳戶的問題。之前一直因為官方文件沒有提供對應的 API,以為不支援,後來觀察到 Wagmi 通過 shimDisconnect 特性實驗性支援了 programmatically disconnect。研究了一下它的原始碼,在此記錄一下吧!
問題描述#
在 Dapp 接入 MetaMask 錢包的時候,Dapp 退出登錄的時候,MetaMask 沒有提供 disconnect API 導致無法斷開錢包和當前網站的連接狀態。下次使用者再次登錄的時候,就無法彈出選擇帳戶的界面。
詳見 issus: https://github.com/MetaMask/metamask-extension/issues/8990
解決方案#
參考 issue 下的回覆和 wagmi 的 shimdisconnect 特性的實現 https://github.com/wevm/wagmi/pull/616/files
核心代碼如下,登錄時通過調用 wallet_requestPermissions 喚起帳戶選擇界面,然後再調用 eth_requestAccounts 獲取使用者選擇的帳戶。
const accounts = await window.ethereum.request({
method: "wallet_requestPermissions",
params: [{
eth_accounts: {}
}]
}).then(() => ethereum.request({
method: 'eth_requestAccounts'
}))
const account = accounts[0]
思考#
-
雖然 MetaMask 和 OKX 錢包可以通過這種方式實現需求,但是這或許是一種無奈之舉。
-
Web3 錢包目前絕大部分都不支援 programmatically disconnect。不知道是出於什麼考量?如果是安全問題,Dapp 控制自身與錢包的連接狀態,應該是合理的,不存在任何安全問題。