经过漫长的兔子洞之旅,这是我解决问题的方法,希望它也对你有用(链接和参考在最后):
起初,我尝试使用 window.etherem.on('accountsChange'...),但从未让它在 Angular 12 中正常工作。我能够让它在 javascript 中工作,但在我们的案例中这不是一个选项。
在我的例子中,我需要监听用户在 Metamask 浏览器扩展中所做的帐户更改,并在我们的网络应用程序中更新帐户。最后,我选择了仅使用“ethers”的方法,该方法有效,并且还具有节省空间的额外好处,因为我们的应用程序当前使用它们的库。
元掩码组件
import {Component, OnInit, OnDestroy, Renderer2} from '@angular/core';
import {ethers} from 'ethers';
...
export class Metamask Component implements OnInit, OnDestroy {
account: string;
selectedAccount = [];
ethereum: any;
constructor(private renderer: Renderer2) {
this.ethereum = new ethers.providers.Web3Provider((<any>window).ethereum, 'any'); }
async ngOnInit() {
this.connectAccount().catch(error => {
console.error('Error in connectAccount', error); });
this.listener();
}
ngOnDestroy() {
this.listener();
}
}
async connectAccount() {
this.selectedAccount = this.ethereum.send('eth_requestAccounts', [])
.then((resolve: any) => {this.account = resolve[0]})
.catch((error: any) => {console.error('Error', error)});
}
listener() {
this.renderer.listen('window', 'focus', event => {
this.selectedAccount = this.ethereum.send('eth_requestAccounts', []).then((resolve: any) => {
this.account = resolve[0]
}).catch((error: any) => {
console.error('Error', error);
});
});
}
}
元掩码模板
<div>{{this.account}}</div>
应用组件模板
...
<app-metamask></app-metamask>
...
我使用的链接和参考资料
How to properly add document.addEventListener to Angular2?
https://docs.ethers.io/v5/api/providers/other/#Web3Provider
https://eips.ethereum.org/EIPS/eip-1193#user-account-exposure-and-account-changes;
在我们的例子中,我不得不放弃 @metamask/providers 方法,因为我无法让 window.ethereum.on('accountsChanged...) 一致地识别 Angular12 中的变化。我假设问题与 Angular 更改检测如何处理主机模板有关,但我对此没有确定的答案。此外,我在访问 window.ethereum.selectedAccount 时遇到问题,每次用户在 Metamask 扩展中选择一个新帐户时都会更新,可能是出于同样的原因。附带说明一下,我在使用 Chrome 开发工具时确实遇到了一些问题,但是一旦我关闭了这些工具并在常规浏览器页面中进行了测试,上述工作对我来说就像预期的那样。
这是一个稍微简化的版本,它只监听更改并在发生更改时更新帐户字符串。它让我再次前进,我希望它对你也有同样的作用。