I came across this just recently as well. I could not find an appropriate typings package from DefinitelyTyped so I started extrapolating from my own usage and the Metamask Documentation and created something that works so far.
Perhaps the community could edit this answer with their own contributions.
In order to use the ethereum
object without TS complaints, I declare it in the window object:
declare global {
interface Window {
ethereum: Ethereumish;
}
}
The makeshift Ethereum Provider types, Ethereumish
looks like this:
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>
}
As you can see, I have not been able to figure out the exact types of many things so far, but the important methods, send
and sendAsync
are accurate in my experience.
Another useful template is something I found inside @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>
}
this can be used when loading a new provider
new ethers.providers.Web3Provider(myProvider: ExternalProvider)
window.ethereum
is injected by MetaMask or any other in-browser wallet. Note that other wallets do not havewindow.ethereum
. ethereum.stackexchange.com/questions/82531/… – Pampasethereum
and most wallets are mobile wallets. – Pampaswindow
variables in TypeScript". Because that is what you want to do, there is nothing Ethereum specific in your question. – PampasWindow
that is relatively simple to do as documented here: #12709574 I'm more interested in how other developers have handled the issue of Web3.js's and MetaMasks's lack of typings for extending the window object. I was digging around the Web3.js repository and found some typings that include the functions available onwindow.ethereum
so that might be a good place to start. – Ashok