Web3.js 扩展窗口界面类型定义
Posted
技术标签:
【中文标题】Web3.js 扩展窗口界面类型定义【英文标题】:Web3.js extending the window interface type definitions 【发布时间】:2021-04-06 20:08:14 【问题描述】:Web3.js
web3
到 window
对象中。
像MetaMask
这样的浏览器钱包将ethereum
注入到window
对象中。
现在在打字稿中,为了减轻编译错误,我将按如下方式进行转换(window as any).ethereum
查看 Web3
存储库和 Wallet 存储库(例如 MetaMask)后,Window
对象没有可导入/可复制的打字稿定义/接口。
一个可能的解决方案是编写我自己的接口并扩展 Window,查看 Window 对象并尝试推断类型 - 不理想
其他使用过 web3.js 和 typescript 的开发者,您是如何解决 VSCode 中的 Window 类型界面问题和智能感知建议的?
【问题讨论】:
从技术上讲,window.ethereum
是由 MetaMask 或任何其他浏览器内钱包注入的。请注意,其他钱包没有有window.ethereum
。 ethereum.stackexchange.com/questions/82531/…
谢谢@MikkoOhtamaa 我假设最受欢迎和采用的钱包是将其注入浏览器的钱包。
您的假设不正确。只有浏览器插件钱包可以注入ethereum
,而且大部分钱包都是手机钱包。
@MikkoOhtamaa 我已更新问题以反映您的解释,感谢您的澄清。
@MikkoOhtamaa 抱歉,但我的问题不在于扩展 Window
的接口,这在此处记录相对简单:***.com/questions/12709074/… 我更感兴趣的是其他开发人员已经处理了 Web3.js 和 MetaMasks 缺少用于扩展窗口对象的类型的问题。我在 Web3.js 存储库中进行了挖掘,发现了一些类型,其中包括 window.ethereum
上可用的功能,因此这可能是一个不错的起点。
【参考方案1】:
我最近也遇到了这个问题。我找不到合适的typings package from DefinitelyTyped,所以我开始根据我自己的用法和Metamask Documentation 进行推断,并创建了一些迄今为止有效的东西。
也许社区可以用他们自己的贡献来编辑这个答案。
为了在没有TS投诉的情况下使用ethereum
对象,我在window对象中声明:
declare global
interface Window
ethereum: Ethereumish;
临时的 Ethereum Provider 类型,Ethereumish
看起来像这样:
import ProviderMessage, ProviderRpcError, ProviderConnectInfo, RequestArguments from 'hardhat/types';
export interface EthereumEvent
connect: ProviderConnectInfo;
disconnect: ProviderRpcError;
accountsChanged: Array<string>;
chainChanged: string;
message: ProviderMessage
type EventKeys = keyof EthereumEvent;
type EventHandler<K extends EventKeys> = (event: EthereumEvent[K]) => void;
export interface Ethereumish
autoRefreshOnNetworkChange: boolean;
chainId: string;
isMetaMask?: boolean;
isStatus?: boolean;
networkVersion: string;
selectedAddress: any;
on<K extends EventKeys>(event: K, eventHandler: EventHandler<K>): void;
enable(): Promise<any>;
request?: (request: method: string, params?: Array<any> ) => Promise<any>
/**
* @deprecated
*/
send?: (request: method: string, params?: Array<any> , callback: (error: any, response: any) => void) => void
sendAsync: (request: RequestArguments) => Promise<unknown>
如您所见,到目前为止,我还无法弄清楚许多事物的确切类型,但重要的方法,send
和 sendAsync
在我的经验中是准确的。
另一个有用的模板是我在 @ethersproject/providers/src.ts/web3-provider.ts 中找到的
export type ExternalProvider =
isMetaMask?: boolean;
isStatus?: boolean;
host?: string;
path?: string;
sendAsync?: (request: method: string, params?: Array<any> , callback: (error: any, response: any) => void) => void
send?: (request: method: string, params?: Array<any> , callback: (error: any, response: any) => void) => void
request?: (request: method: string, params?: Array<any> ) => Promise<any>
这可以在加载新的提供者时使用
new ethers.providers.Web3Provider(myProvider: ExternalProvider)
【讨论】:
这个来自 metamask 的 repo 似乎提供了类型定义MetaMaskInpageProvider
: github.com/MetaMask/providers【参考方案2】:
官方 Metamask Provider 存储库现在导出您可以/应该用于扩展 Window 界面的类型。
与@Felipe 的回答相同,使用MetamaskInpageProvider
而不是Ethereumish
,
import MetaMaskInpageProvider from "@metamask/providers";
declare global
interface Window
ethereum: MetaMaskInpageProvider;
【讨论】:
以上是关于Web3.js 扩展窗口界面类型定义的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 @solana/web3.js 从 Solana 中的自定义令牌中删除铸币权限?