(
payload: JsonRpcPayload,
// Used "null" value to match the legacy version
// eslint-disable-next-line @typescript-eslint/ban-types
callback: (err: Error | null, response?: JsonRpcResponse) => void,
): void;
}
export interface LegacySendAsyncProvider {
sendAsync(
payload: JsonRpcPayload,
): Promise>;
}
export interface LegacyRequestProvider {
request(
payload: JsonRpcPayload,
// eslint-disable-next-line @typescript-eslint/ban-types
callback: (err: Error | null, response: JsonRpcResponse) => void,
): void;
}
export interface SimpleProvider {
request, ResponseType = Web3APIReturnType>(
args: Web3APIPayload,
): Promise | unknown>;
}
export interface ProviderInfo {
chainId: string;
}
export type ProviderChainId = string;
export type ProviderAccounts = string[];
export type Eip1193EventName =
| 'connect'
| 'disconnect'
| 'message'
| 'chainChanged'
| 'accountsChanged';
export interface EIP1193Provider extends SimpleProvider {
on(event: 'connect', listener: (info: ProviderInfo) => void): void;
on(event: 'disconnect', listener: (error: ProviderRpcError) => void): void;
on(event: 'message', listener: (message: ProviderMessage) => void): void;
on(event: 'chainChanged', listener: (chainId: ProviderChainId) => void): void;
on(event: 'accountsChanged', listener: (accounts: ProviderAccounts) => void): void;
removeListener(event: 'connect', listener: (info: ProviderInfo) => void): void;
removeListener(event: 'disconnect', listener: (error: ProviderRpcError) => void): void;
removeListener(event: 'message', listener: (message: ProviderMessage) => void): void;
removeListener(event: 'chainChanged', listener: (chainId: ProviderChainId) => void): void;
removeListener(event: 'accountsChanged', listener: (accounts: ProviderAccounts) => void): void;
}
export type Eip1193Compatible = Omit<
// eslint-disable-next-line no-use-before-define
Omit,
'asEIP1193Provider'
> & {
request<
Method extends Web3APIMethod,
ResultType = Web3APIReturnType | unknown,
>(
request: Web3APIPayload,
): Promise;
};
// Provider interface compatible with EIP-1193
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md
export abstract class Web3BaseProvider
implements LegacySendProvider, LegacySendAsyncProvider, EIP1193Provider
{
public static isWeb3Provider(provider: unknown) {
return (
provider instanceof Web3BaseProvider ||
Boolean(provider && (provider as { [symbol]: boolean })[symbol])
);
}
// To match an object "instanceof" does not work if
// matcher class and object is using different package versions
// to overcome this bottleneck used this approach.
// The symbol value for one string will always remain same regardless of package versions
// eslint-disable-next-line class-methods-use-this
public get [symbol]() {
return true;
}
public abstract getStatus(): Web3ProviderStatus;
public abstract supportsSubscriptions(): boolean;
/**
* @deprecated Please use `.request` instead.
* @param payload - Request Payload
* @param callback - Callback
*/
public send(
payload: JsonRpcPayload,
// eslint-disable-next-line @typescript-eslint/ban-types
callback: (err: Error | null, response?: JsonRpcResponse) => void,
) {
this.request, ResultType>(
payload as Web3APIPayload>,
)
.then(response => {
// eslint-disable-next-line no-null/no-null
callback(null, response);
})
.catch((err: Error | Web3Error) => {
callback(err);
});
}
/**
* @deprecated Please use `.request` instead.
* @param payload - Request Payload
*/
public async sendAsync(payload: JsonRpcPayload) {
return this.request(payload as Web3APIPayload>) as Promise<
JsonRpcResponse
>;
}
/**
* Modify the return type of the request method to be fully compatible with EIP-1193
*
* [deprecated] In the future major releases (\>= v5) all providers are supposed to be fully compatible with EIP-1193.
* So this method will not be needed and would not be available in the future.
*
* @returns A new instance of the provider with the request method fully compatible with EIP-1193
*
* @example
* ```ts
* const provider = new Web3HttpProvider('http://localhost:8545');
* const fullyCompatibleProvider = provider.asEIP1193Provider();
* const result = await fullyCompatibleProvider.request({ method: 'qrl_getBalance' });
* console.log(result); // '0x0234c8a3397aab58' or something like that
* ```
*/
public asEIP1193Provider(): Eip1193Compatible {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const newObj = Object.create(this) as Eip1193Compatible;
// eslint-disable-next-line @typescript-eslint/unbound-method
const originalRequest = newObj.request;
newObj.request = async function request(
args: Web3APIPayload>,
): Promise {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const response = (await originalRequest(args)) as JsonRpcResponseWithResult;
return response.result;
} as typeof newObj.request;
// @ts-expect-error the property should not be available in the new object because of using Object.create(this).
// But it is available if we do not delete it.
newObj.asEIP1193Provider = undefined; // to prevent the user for calling this method again
return newObj;
}
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#request
public abstract request<
Method extends Web3APIMethod,
ResultType = Web3APIReturnType | unknown,
>(args: Web3APIPayload): Promise>;
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#events
public abstract on(
type: 'disconnect',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract on(
type: 'message' | string,
listener:
| Web3Eip1193ProviderEventCallback
| Web3ProviderMessageEventCallback,
): void;
// for old providers
public abstract on(
type: 'data' | string,
listener:
| Web3Eip1193ProviderEventCallback
| Web3ProviderMessageEventCallback,
): void;
public abstract on(
type: 'connect',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract on(
type: 'chainChanged',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract on(
type: 'accountsChanged',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract removeListener(
type: 'disconnect',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract removeListener(
type: 'message' | string,
listener: Web3Eip1193ProviderEventCallback | Web3ProviderEventCallback,
): void;
public abstract removeListener(
type: 'connect',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract removeListener(
type: 'chainChanged',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract removeListener(
type: 'accountsChanged',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract once(
type: 'disconnect',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract once(
type: 'message' | string,
listener: Web3Eip1193ProviderEventCallback | Web3ProviderEventCallback,
): void;
public abstract once(
type: 'connect',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract once(
type: 'chainChanged',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract once(
type: 'accountsChanged',
listener: Web3Eip1193ProviderEventCallback,
): void;
public abstract removeAllListeners?(type: string): void;
public abstract connect(): void;
public abstract disconnect(code?: number, data?: string): void;
public abstract reset(): void;
}
export type SupportedProviders =
| EIP1193Provider
| Web3BaseProvider
| LegacyRequestProvider
| LegacySendProvider
| LegacySendAsyncProvider
| SimpleProvider;
export type Web3BaseProviderConstructor = new (
url: string,
net?: Socket,
) => Web3BaseProvider;