Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@metamask/providers

Package Overview
Dependencies
Maintainers
9
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@metamask/providers - npm Package Compare versions

Comparing version 10.2.1 to 11.0.0

14

CHANGELOG.md

@@ -9,2 +9,13 @@ # Changelog

## [11.0.0]
### Changed
- **BREAKING**: Minimum Node.js version 16 ([#254](https://github.com/MetaMask/providers/pull/254))
- Support Flask and Beta in the external extension provider ([#252](https://github.com/MetaMask/providers/pull/252))
- Bump @metamask/safe-event-emitter from 2.0.0 to 3.0.0 ([#255](https://github.com/MetaMask/providers/pull/255))
### Fixed
- Fix console warning about deprecated `webextension-polyfill-ts` ([#249](https://github.com/MetaMask/providers/pull/249))
- Prevent `accountsChanged` + `eth_accounts` callback loop ([#248](https://github.com/MetaMask/providers/pull/248))
- If you listen to the provider `accountsChanged` event, modify the returned accounts, then call `eth_accounts`, it was possible to enter an infinite loop. This was caused by the provider mistakenly thinking the accounts had changed because of the mutation performed in the event listener, triggering redundant `accountsChanged` events. This was fixed; there should be no more redundant `accountsChanged` events and no infinite loop.
## [10.2.1]

@@ -213,3 +224,4 @@ ### Changed

[Unreleased]: https://github.com/MetaMask/providers/compare/v10.2.1...HEAD
[Unreleased]: https://github.com/MetaMask/providers/compare/v11.0.0...HEAD
[11.0.0]: https://github.com/MetaMask/providers/compare/v10.2.1...v11.0.0
[10.2.1]: https://github.com/MetaMask/providers/compare/v10.2.0...v10.2.1

@@ -216,0 +228,0 @@ [10.2.0]: https://github.com/MetaMask/providers/compare/v10.1.0...v10.2.0

56

dist/BaseProvider.d.ts
import SafeEventEmitter from '@metamask/safe-event-emitter';
import { JsonRpcEngine, JsonRpcId, JsonRpcVersion, JsonRpcMiddleware } from 'json-rpc-engine';
import { ConsoleLike, Maybe } from './utils';
export interface UnvalidatedJsonRpcRequest {
export declare type UnvalidatedJsonRpcRequest = {
id?: JsonRpcId;

@@ -9,4 +9,4 @@ jsonrpc?: JsonRpcVersion;

params?: unknown;
}
export interface BaseProviderOptions {
};
export declare type BaseProviderOptions = {
/**

@@ -25,4 +25,4 @@ * The logging API to use.

rpcMiddleware?: JsonRpcMiddleware<unknown, unknown>[];
}
export interface RequestArguments {
};
export declare type RequestArguments = {
/** The RPC method to request. */

@@ -32,4 +32,4 @@ method: string;

params?: unknown[] | Record<string, unknown>;
}
export interface BaseProviderState {
};
export declare type BaseProviderState = {
accounts: null | string[];

@@ -40,3 +40,3 @@ isConnected: boolean;

isPermanentlyDisconnected: boolean;
}
};
/**

@@ -46,5 +46,5 @@ * An abstract class implementing the EIP-1193 interface. Implementers must:

* 1. At initialization, push a middleware to the internal `_rpcEngine` that
* hands off requests to the server and receives responses in return.
* hands off requests to the server and receives responses in return.
* 2. At initialization, retrieve initial state and call
* {@link BaseProvider._initializeState} **once**.
* {@link BaseProvider._initializeState} **once**.
* 3. Ensure that the provider's state is synchronized with the wallet.

@@ -70,6 +70,9 @@ * 4. Ensure that notifications are received and emitted as appropriate.

/**
* @param options - An options bag
* @param options.logger - The logging API to use. Default: console
* Create a new instance of the provider.
*
* @param options - An options bag.
* @param options.logger - The logging API to use. Default: `console`.
* @param options.maxEventListeners - The maximum number of event
* listeners. Default: 100
* listeners. Default: 100.
* @param options.rpcMiddleware - The RPC middleware stack. Default: [].
*/

@@ -79,2 +82,4 @@ constructor({ logger, maxEventListeners, rpcMiddleware, }?: BaseProviderOptions);

* Returns whether the provider can process RPC requests.
*
* @returns Whether the provider can process RPC requests.
*/

@@ -94,3 +99,3 @@ isConnected(): boolean;

/**
* **MUST** be called by child classes.
* MUST be called by child classes.
*

@@ -104,4 +109,8 @@ * Sets initial state if provided and marks this provider as initialized.

* @param initialState - The provider's initial state.
* @emits BaseProvider#_initialized
* @emits BaseProvider#connect - If `initialState` is defined.
* @param initialState.accounts - The user's accounts.
* @param initialState.chainId - The chain ID.
* @param initialState.isUnlocked - Whether the user has unlocked MetaMask.
* @param initialState.networkVersion - The network version.
* @fires BaseProvider#_initialized - If `initialState` is defined.
* @fires BaseProvider#connect - If `initialState` is defined.
*/

@@ -120,2 +129,3 @@ protected _initializeState(initialState?: {

* @param callback - The consumer's callback.
* @returns The result of the RPC request.
*/

@@ -128,3 +138,3 @@ protected _rpcRequest(payload: UnvalidatedJsonRpcRequest | UnvalidatedJsonRpcRequest[], callback: (...args: any[]) => void): void;

* @param chainId - The ID of the newly connected chain.
* @emits MetaMaskInpageProvider#connect
* @fires MetaMaskInpageProvider#connect
*/

@@ -137,7 +147,7 @@ protected _handleConnect(chainId: string): void;

* Error codes per the CloseEvent status codes as required by EIP-1193:
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes.
*
* @param isRecoverable - Whether the disconnection is recoverable.
* @param errorMessage - A custom error message.
* @emits BaseProvider#disconnect
* @fires BaseProvider#disconnect - If the disconnection is not recoverable.
*/

@@ -153,3 +163,3 @@ protected _handleDisconnect(isRecoverable: boolean, errorMessage?: string): void;

*
* @emits BaseProvider#chainChanged
* @fires BaseProvider#chainChanged
* @param networkInfo - An object with network info.

@@ -159,5 +169,5 @@ * @param networkInfo.chainId - The latest chain ID.

protected _handleChainChanged({ chainId, }?: {
chainId?: string;
networkVersion?: string;
}): void;
chainId?: string | undefined;
networkVersion?: string | undefined;
} | undefined): void;
/**

@@ -164,0 +174,0 @@ * Called when accounts may have changed. Diffs the new accounts value with

@@ -17,5 +17,5 @@ "use strict";

* 1. At initialization, push a middleware to the internal `_rpcEngine` that
* hands off requests to the server and receives responses in return.
* hands off requests to the server and receives responses in return.
* 2. At initialization, retrieve initial state and call
* {@link BaseProvider._initializeState} **once**.
* {@link BaseProvider._initializeState} **once**.
* 3. Ensure that the provider's state is synchronized with the wallet.

@@ -26,6 +26,9 @@ * 4. Ensure that notifications are received and emitted as appropriate.

/**
* @param options - An options bag
* @param options.logger - The logging API to use. Default: console
* Create a new instance of the provider.
*
* @param options - An options bag.
* @param options.logger - The logging API to use. Default: `console`.
* @param options.maxEventListeners - The maximum number of event
* listeners. Default: 100
* listeners. Default: 100.
* @param options.rpcMiddleware - The RPC middleware stack. Default: [].
*/

@@ -37,3 +40,5 @@ constructor({ logger = console, maxEventListeners = 100, rpcMiddleware = [], } = {}) {

// Private state
this._state = Object.assign({}, BaseProvider._defaultState);
this._state = {
...BaseProvider._defaultState,
};
// Public state

@@ -63,2 +68,4 @@ this.selectedAddress = null;

* Returns whether the provider can process RPC requests.
*
* @returns Whether the provider can process RPC requests.
*/

@@ -101,3 +108,3 @@ isConnected() {

return new Promise((resolve, reject) => {
this._rpcRequest({ method, params }, utils_1.getRpcPromiseCallback(resolve, reject));
this._rpcRequest({ method, params }, (0, utils_1.getRpcPromiseCallback)(resolve, reject));
});

@@ -109,3 +116,3 @@ }

/**
* **MUST** be called by child classes.
* MUST be called by child classes.
*

@@ -119,7 +126,11 @@ * Sets initial state if provided and marks this provider as initialized.

* @param initialState - The provider's initial state.
* @emits BaseProvider#_initialized
* @emits BaseProvider#connect - If `initialState` is defined.
* @param initialState.accounts - The user's accounts.
* @param initialState.chainId - The chain ID.
* @param initialState.isUnlocked - Whether the user has unlocked MetaMask.
* @param initialState.networkVersion - The network version.
* @fires BaseProvider#_initialized - If `initialState` is defined.
* @fires BaseProvider#connect - If `initialState` is defined.
*/
_initializeState(initialState) {
if (this._state.initialized === true) {
if (this._state.initialized) {
throw new Error('Provider already initialized.');

@@ -146,5 +157,6 @@ }

* @param callback - The consumer's callback.
* @returns The result of the RPC request.
*/
_rpcRequest(payload, callback) {
let cb = callback;
let callbackWrapper = callback;
if (!Array.isArray(payload)) {

@@ -157,10 +169,10 @@ if (!payload.jsonrpc) {

// handle accounts changing
cb = (err, res) => {
this._handleAccountsChanged(res.result || [], payload.method === 'eth_accounts');
callback(err, res);
callbackWrapper = (error, response) => {
this._handleAccountsChanged(response.result ?? [], payload.method === 'eth_accounts');
callback(error, response);
};
}
return this._rpcEngine.handle(payload, cb);
return this._rpcEngine.handle(payload, callbackWrapper);
}
return this._rpcEngine.handle(payload, cb);
return this._rpcEngine.handle(payload, callbackWrapper);
}

@@ -172,3 +184,3 @@ /**

* @param chainId - The ID of the newly connected chain.
* @emits MetaMaskInpageProvider#connect
* @fires MetaMaskInpageProvider#connect
*/

@@ -187,7 +199,7 @@ _handleConnect(chainId) {

* Error codes per the CloseEvent status codes as required by EIP-1193:
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes.
*
* @param isRecoverable - Whether the disconnection is recoverable.
* @param errorMessage - A custom error message.
* @emits BaseProvider#disconnect
* @fires BaseProvider#disconnect - If the disconnection is not recoverable.
*/

@@ -201,3 +213,3 @@ _handleDisconnect(isRecoverable, errorMessage) {

error = new eth_rpc_errors_1.EthereumRpcError(1013, // Try again later
errorMessage || messages_1.default.errors.disconnected());
errorMessage ?? messages_1.default.errors.disconnected());
this._log.debug(error);

@@ -207,3 +219,3 @@ }

error = new eth_rpc_errors_1.EthereumRpcError(1011, // Internal error
errorMessage || messages_1.default.errors.permanentlyDisconnected());
errorMessage ?? messages_1.default.errors.permanentlyDisconnected());
this._log.error(error);

@@ -227,3 +239,3 @@ this.chainId = null;

*
* @emits BaseProvider#chainChanged
* @fires BaseProvider#chainChanged
* @param networkInfo - An object with network info.

@@ -233,3 +245,3 @@ * @param networkInfo.chainId - The latest chain ID.

_handleChainChanged({ chainId, } = {}) {
if (!utils_1.isValidChainId(chainId)) {
if (!(0, utils_1.isValidChainId)(chainId)) {
this._log.error(messages_1.default.errors.invalidNetworkParams(), { chainId });

@@ -269,3 +281,3 @@ return;

// emit accountsChanged if anything about the accounts array has changed
if (!fast_deep_equal_1.default(this._state.accounts, _accounts)) {
if (!(0, fast_deep_equal_1.default)(this._state.accounts, _accounts)) {
// we should always have the correct accounts even before eth_accounts

@@ -283,3 +295,4 @@ // returns

if (this._state.initialized) {
this.emit('accountsChanged', _accounts);
const _nextAccounts = [..._accounts];
this.emit('accountsChanged', _nextAccounts);
}

@@ -307,3 +320,3 @@ }

this._state.isUnlocked = isUnlocked;
this._handleAccountsChanged(accounts || []);
this._handleAccountsChanged(accounts ?? []);
}

@@ -310,0 +323,0 @@ }

import { StreamProvider } from '../StreamProvider';
export declare function createExternalExtensionProvider(): StreamProvider;
export declare type ExtensionType = 'stable' | 'flask' | 'beta' | string;
/**
* Creates an external extension provider for the given extension type or ID.
*
* @param typeOrId - The extension type or ID.
* @returns The external extension provider.
*/
export declare function createExternalExtensionProvider(typeOrId?: ExtensionType): StreamProvider;

@@ -7,14 +7,20 @@ "use strict";

exports.createExternalExtensionProvider = void 0;
const detect_browser_1 = require("detect-browser");
const extension_port_stream_1 = __importDefault(require("extension-port-stream"));
const detect_browser_1 = require("detect-browser");
const external_extension_config_json_1 = __importDefault(require("./external-extension-config.json"));
const MetaMaskInpageProvider_1 = require("../MetaMaskInpageProvider");
const StreamProvider_1 = require("../StreamProvider");
const utils_1 = require("../utils");
const external_extension_config_json_1 = __importDefault(require("./external-extension-config.json"));
const browser = detect_browser_1.detect();
function createExternalExtensionProvider() {
const browser = (0, detect_browser_1.detect)();
/**
* Creates an external extension provider for the given extension type or ID.
*
* @param typeOrId - The extension type or ID.
* @returns The external extension provider.
*/
function createExternalExtensionProvider(typeOrId = 'stable') {
let provider;
try {
const currentMetaMaskId = getMetaMaskId();
const metamaskPort = chrome.runtime.connect(currentMetaMaskId);
const extensionId = getExtensionId(typeOrId);
const metamaskPort = chrome.runtime.connect(extensionId);
const pluginStream = new extension_port_stream_1.default(metamaskPort);

@@ -24,3 +30,3 @@ provider = new StreamProvider_1.StreamProvider(pluginStream, {

logger: console,
rpcMiddleware: utils_1.getDefaultExternalMiddleware(console),
rpcMiddleware: (0, utils_1.getDefaultExternalMiddleware)(console),
});

@@ -30,2 +36,3 @@ // This is asynchronous but merely logs an error and does not throw upon

// constructor.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
provider.initialize();

@@ -40,12 +47,12 @@ }

exports.createExternalExtensionProvider = createExternalExtensionProvider;
function getMetaMaskId() {
switch (browser === null || browser === void 0 ? void 0 : browser.name) {
case 'chrome':
return external_extension_config_json_1.default.CHROME_ID;
case 'firefox':
return external_extension_config_json_1.default.FIREFOX_ID;
default:
return external_extension_config_json_1.default.CHROME_ID;
}
/**
* Gets the extension ID for the given extension type or ID.
*
* @param typeOrId - The extension type or ID.
* @returns The extension ID.
*/
function getExtensionId(typeOrId) {
const ids = browser?.name === 'firefox' ? external_extension_config_json_1.default.firefoxIds : external_extension_config_json_1.default.chromeIds;
return ids[typeOrId] ?? typeOrId;
}
//# sourceMappingURL=createExternalExtensionProvider.js.map
{
"CHROME_ID": "nkbihfbeogaeaoehlefnkodbefgpgknn",
"FIREFOX_ID": "webextension@metamask.io"
"chromeIds": {
"stable": "nkbihfbeogaeaoehlefnkodbefgpgknn",
"beta": "pbbkamfgmaedccnfkmjcofcecjhfgldn",
"flask": "ljfoeinjpaedjfecbmggjgodbgkmjkjk"
},
"firefoxIds": {
"stable": "webextension@metamask.io",
"beta": "webextension-beta@metamask.io",
"flask": "webextension-flask@metamask.io"
}
}
/// <reference types="node" />
import { Duplex } from 'stream';
import { MetaMaskInpageProvider, MetaMaskInpageProviderOptions } from './MetaMaskInpageProvider';
interface InitializeProviderOptions extends MetaMaskInpageProviderOptions {
declare type InitializeProviderOptions = {
/**

@@ -17,3 +17,3 @@ * The stream used to connect to the wallet.

shouldShimWeb3?: boolean;
}
} & MetaMaskInpageProviderOptions;
/**

@@ -29,2 +29,3 @@ * Initializes a MetaMaskInpageProvider and (optionally) assigns it as window.ethereum.

* @param options.shouldShimWeb3 - Whether a window.web3 shim should be injected.
* @param options.logger - The logging API to use. Default: `console`.
* @returns The initialized provider (whether set or not).

@@ -31,0 +32,0 @@ */

@@ -16,2 +16,3 @@ "use strict";

* @param options.shouldShimWeb3 - Whether a window.web3 shim should be injected.
* @param options.logger - The logging API to use. Default: `console`.
* @returns The initialized provider (whether set or not).

@@ -34,3 +35,3 @@ */

if (shouldShimWeb3) {
shimWeb3_1.shimWeb3(proxiedProvider, logger);
(0, shimWeb3_1.shimWeb3)(proxiedProvider, logger);
}

@@ -37,0 +38,0 @@ return proxiedProvider;

/// <reference types="node" />
import type { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine';
import type { Duplex } from 'stream';
import type { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine';
import type { UnvalidatedJsonRpcRequest } from './BaseProvider';
import { AbstractStreamProvider, StreamProviderOptions } from './StreamProvider';
export interface SendSyncJsonRpcRequest extends JsonRpcRequest<unknown> {
export declare type SendSyncJsonRpcRequest = {
method: 'eth_accounts' | 'eth_coinbase' | 'eth_uninstallFilter' | 'net_version';
}
export interface MetaMaskInpageProviderOptions extends Partial<Omit<StreamProviderOptions, 'rpcMiddleware'>> {
} & JsonRpcRequest<unknown>;
export declare type MetaMaskInpageProviderOptions = {
/**

@@ -14,4 +14,5 @@ * Whether the provider should send page metadata.

shouldSendMetadata?: boolean;
}
interface SentWarningsState {
jsonRpcStreamName?: string | undefined;
} & Partial<Omit<StreamProviderOptions, 'rpcMiddleware'>>;
declare type SentWarningsState = {
enable: boolean;

@@ -26,3 +27,3 @@ experimentalMethods: boolean;

};
}
};
/**

@@ -44,11 +45,13 @@ * The name of the stream consumed by {@link MetaMaskInpageProvider}.

/**
* @param connectionStream - A Node.js duplex stream
* @param options - An options bag
* Creates a new `MetaMaskInpageProvider`.
*
* @param connectionStream - A Node.js duplex stream.
* @param options - An options bag.
* @param options.jsonRpcStreamName - The name of the internal JSON-RPC stream.
* Default: metamask-provider
* @param options.logger - The logging API to use. Default: console
* Default: `metamask-provider`.
* @param options.logger - The logging API to use. Default: `console`.
* @param options.maxEventListeners - The maximum number of event
* listeners. Default: 100
* listeners. Default: 100.
* @param options.shouldSendMetadata - Whether the provider should
* send page metadata. Default: true
* send page metadata. Default: `true`.
*/

@@ -66,3 +69,3 @@ constructor(connectionStream: Duplex, { jsonRpcStreamName, logger, maxEventListeners, shouldSendMetadata, }?: MetaMaskInpageProviderOptions);

* about deprecated events:
* addListener, on, once, prependListener, prependOnceListener
* `addListener`, `on`, `once`, `prependListener`, `prependOnceListener`.
*/

@@ -79,7 +82,7 @@ addListener(eventName: string, listener: (...args: unknown[]) => void): this;

* Error codes per the CloseEvent status codes as required by EIP-1193:
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes.
*
* @param isRecoverable - Whether the disconnection is recoverable.
* @param errorMessage - A custom error message.
* @emits BaseProvider#disconnect
* @fires BaseProvider#disconnect - If the disconnection is not recoverable.
*/

@@ -89,6 +92,8 @@ protected _handleDisconnect(isRecoverable: boolean, errorMessage?: string): void;

* Warns of deprecation for the given event, if applicable.
*
* @param eventName - The name of the event.
*/
protected _warnOfDeprecation(eventName: string): void;
/**
* Equivalent to: ethereum.request('eth_requestAccounts')
* Equivalent to: `ethereum.request('eth_requestAccounts')`.
*

@@ -130,2 +135,4 @@ * @deprecated Use request({ method: 'eth_requestAccounts' }) instead.

*
* @param payload - A JSON-RPC request object.
* @returns A JSON-RPC response object.
* @deprecated

@@ -143,2 +150,4 @@ */

* about its experimental nature.
*
* @returns The experimental _metamask API.
*/

@@ -149,3 +158,3 @@ protected _getExperimentalApi(): {

*
* @returns Promise resolving to true if MetaMask is currently unlocked
* @returns Promise resolving to true if MetaMask is currently unlocked.
*/

@@ -155,2 +164,4 @@ isUnlocked: () => Promise<boolean>;

* Make a batch RPC request.
*
* @param requests - The RPC requests to make.
*/

@@ -164,3 +175,3 @@ requestBatch: (requests: UnvalidatedJsonRpcRequest[]) => Promise<unknown>;

*
* @emits MetamaskInpageProvider#networkChanged
* @fires MetamaskInpageProvider#networkChanged
* @param networkInfo - An object with network info.

@@ -167,0 +178,0 @@ * @param networkInfo.chainId - The latest chain ID.

@@ -8,6 +8,6 @@ "use strict";

const eth_rpc_errors_1 = require("eth-rpc-errors");
const messages_1 = __importDefault(require("./messages"));
const siteMetadata_1 = require("./siteMetadata");
const messages_1 = __importDefault(require("./messages"));
const StreamProvider_1 = require("./StreamProvider");
const utils_1 = require("./utils");
const StreamProvider_1 = require("./StreamProvider");
/**

@@ -19,13 +19,15 @@ * The name of the stream consumed by {@link MetaMaskInpageProvider}.

/**
* @param connectionStream - A Node.js duplex stream
* @param options - An options bag
* Creates a new `MetaMaskInpageProvider`.
*
* @param connectionStream - A Node.js duplex stream.
* @param options - An options bag.
* @param options.jsonRpcStreamName - The name of the internal JSON-RPC stream.
* Default: metamask-provider
* @param options.logger - The logging API to use. Default: console
* Default: `metamask-provider`.
* @param options.logger - The logging API to use. Default: `console`.
* @param options.maxEventListeners - The maximum number of event
* listeners. Default: 100
* listeners. Default: 100.
* @param options.shouldSendMetadata - Whether the provider should
* send page metadata. Default: true
* send page metadata. Default: `true`.
*/
constructor(connectionStream, { jsonRpcStreamName = exports.MetaMaskInpageProviderStreamName, logger = console, maxEventListeners, shouldSendMetadata, } = {}) {
constructor(connectionStream, { jsonRpcStreamName = exports.MetaMaskInpageProviderStreamName, logger = console, maxEventListeners = 100, shouldSendMetadata, } = {}) {
super(connectionStream, {

@@ -35,3 +37,3 @@ jsonRpcStreamName,

maxEventListeners,
rpcMiddleware: utils_1.getDefaultExternalMiddleware(logger),
rpcMiddleware: (0, utils_1.getDefaultExternalMiddleware)(logger),
});

@@ -54,2 +56,3 @@ this._sentWarnings = {

// the time of writing.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this._initializeStateAsync();

@@ -78,7 +81,9 @@ this.networkVersion = null;

if (document.readyState === 'complete') {
siteMetadata_1.sendSiteMetadata(this._rpcEngine, this._log);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(0, siteMetadata_1.sendSiteMetadata)(this._rpcEngine, this._log);
}
else {
const domContentLoadedHandler = () => {
siteMetadata_1.sendSiteMetadata(this._rpcEngine, this._log);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(0, siteMetadata_1.sendSiteMetadata)(this._rpcEngine, this._log);
window.removeEventListener('DOMContentLoaded', domContentLoadedHandler);

@@ -105,3 +110,3 @@ };

* about deprecated events:
* addListener, on, once, prependListener, prependOnceListener
* `addListener`, `on`, `once`, `prependListener`, `prependOnceListener`.
*/

@@ -136,7 +141,7 @@ addListener(eventName, listener) {

* Error codes per the CloseEvent status codes as required by EIP-1193:
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes.
*
* @param isRecoverable - Whether the disconnection is recoverable.
* @param errorMessage - A custom error message.
* @emits BaseProvider#disconnect
* @fires BaseProvider#disconnect - If the disconnection is not recoverable.
*/

@@ -151,6 +156,8 @@ _handleDisconnect(isRecoverable, errorMessage) {

* Warns of deprecation for the given event, if applicable.
*
* @param eventName - The name of the event.
*/
_warnOfDeprecation(eventName) {
var _a;
if (((_a = this._sentWarnings) === null || _a === void 0 ? void 0 : _a.events[eventName]) === false) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare
if (this._sentWarnings?.events[eventName] === false) {
this._log.warn(messages_1.default.warnings.events[eventName]);

@@ -164,3 +171,3 @@ this._sentWarnings.events[eventName] = true;

/**
* Equivalent to: ethereum.request('eth_requestAccounts')
* Equivalent to: `ethereum.request('eth_requestAccounts')`.
*

@@ -170,3 +177,3 @@ * @deprecated Use request({ method: 'eth_requestAccounts' }) instead.

*/
enable() {
async enable() {
if (!this._sentWarnings.enable) {

@@ -178,3 +185,3 @@ this._log.warn(messages_1.default.warnings.enableDeprecation);

try {
this._rpcRequest({ method: 'eth_requestAccounts', params: [] }, utils_1.getRpcPromiseCallback(resolve, reject));
this._rpcRequest({ method: 'eth_requestAccounts', params: [] }, (0, utils_1.getRpcPromiseCallback)(resolve, reject));
}

@@ -186,2 +193,3 @@ catch (error) {

}
// eslint-disable-next-line @typescript-eslint/promise-function-async
send(methodOrPayload, callbackOrArgs) {

@@ -196,3 +204,3 @@ if (!this._sentWarnings.send) {

try {
this._rpcRequest({ method: methodOrPayload, params: callbackOrArgs }, utils_1.getRpcPromiseCallback(resolve, reject, false));
this._rpcRequest({ method: methodOrPayload, params: callbackOrArgs }, (0, utils_1.getRpcPromiseCallback)(resolve, reject, false));
}

@@ -214,2 +222,4 @@ catch (error) {

*
* @param payload - A JSON-RPC request object.
* @returns A JSON-RPC response object.
* @deprecated

@@ -224,3 +234,3 @@ */

case 'eth_coinbase':
result = this.selectedAddress || null;
result = this.selectedAddress ?? null;
break;

@@ -232,3 +242,3 @@ case 'eth_uninstallFilter':

case 'net_version':
result = this.networkVersion || null;
result = this.networkVersion ?? null;
break;

@@ -249,2 +259,4 @@ default:

* about its experimental nature.
*
* @returns The experimental _metamask API.
*/

@@ -256,3 +268,3 @@ _getExperimentalApi() {

*
* @returns Promise resolving to true if MetaMask is currently unlocked
* @returns Promise resolving to true if MetaMask is currently unlocked.
*/

@@ -269,2 +281,4 @@ isUnlocked: async () => {

* Make a batch RPC request.
*
* @param requests - The RPC requests to make.
*/

@@ -279,3 +293,3 @@ requestBatch: async (requests) => {

return new Promise((resolve, reject) => {
this._rpcRequest(requests, utils_1.getRpcPromiseCallback(resolve, reject));
this._rpcRequest(requests, (0, utils_1.getRpcPromiseCallback)(resolve, reject));
});

@@ -298,3 +312,3 @@ },

*
* @emits MetamaskInpageProvider#networkChanged
* @fires MetamaskInpageProvider#networkChanged
* @param networkInfo - An object with network info.

@@ -301,0 +315,0 @@ * @param networkInfo.chainId - The latest chain ID.

@@ -20,8 +20,7 @@ "use strict";

return (req, _res, next) => {
if (sentWarnings.ethDecryptDeprecation === false &&
req.method === 'eth_decrypt') {
if (!sentWarnings.ethDecryptDeprecation && req.method === 'eth_decrypt') {
log.warn(messages_1.default.warnings.rpc.ethDecryptDeprecation);
sentWarnings.ethDecryptDeprecation = true;
}
else if (sentWarnings.ethGetEncryptionPublicKeyDeprecation === false &&
else if (!sentWarnings.ethGetEncryptionPublicKeyDeprecation &&
req.method === 'eth_getEncryptionPublicKey') {

@@ -28,0 +27,0 @@ log.warn(messages_1.default.warnings.rpc.ethGetEncryptionPublicKeyDeprecation);

@@ -35,4 +35,5 @@ "use strict";

/**
* Gets site metadata and returns it
* Get site metadata.
*
* @returns The site metadata.
*/

@@ -46,3 +47,6 @@ async function getSiteMetadata() {

/**
* Extracts a name for the site from the DOM
* Extract a name for the site from the DOM.
*
* @param windowObject - The window object to extract the site name from.
* @returns The site name.
*/

@@ -65,4 +69,6 @@ function getSiteName(windowObject) {

/**
* Extracts an icon for the site from the DOM
* @returns an icon URL
* Extract an icon for the site from the DOM.
*
* @param windowObject - The window object to extract the site icon from.
* @returns An icon URL, if one exists.
*/

@@ -72,3 +78,3 @@ async function getSiteIcon(windowObject) {

const icons = document.querySelectorAll('head > link[rel~="icon"]');
for (const icon of icons) {
for (const icon of Array.from(icons)) {
if (icon && (await imgExists(icon.href))) {

@@ -81,7 +87,8 @@ return icon.href;

/**
* Returns whether the given image URL exists
* @param url - the url of the image
* Return whether the given image URL exists.
*
* @param url - The url of the image.
* @returns Whether the image exists.
*/
function imgExists(url) {
async function imgExists(url) {
return new Promise((resolve, reject) => {

@@ -94,4 +101,4 @@ try {

}
catch (e) {
reject(e);
catch (error) {
reject(error);
}

@@ -98,0 +105,0 @@ });

/// <reference types="node" />
import type { Duplex } from 'stream';
import SafeEventEmitter from '@metamask/safe-event-emitter';
import type { JsonRpcMiddleware } from 'json-rpc-engine';
import type { Duplex } from 'stream';
import { BaseProvider, BaseProviderOptions } from './BaseProvider';
export interface StreamProviderOptions extends BaseProviderOptions {
export declare type StreamProviderOptions = {
/**

@@ -11,8 +11,8 @@ * The name of the stream used to connect to the wallet.

jsonRpcStreamName: string;
}
export interface JsonRpcConnection {
} & BaseProviderOptions;
export declare type JsonRpcConnection = {
events: SafeEventEmitter;
middleware: JsonRpcMiddleware<unknown, unknown>;
stream: Duplex;
}
};
/**

@@ -27,12 +27,15 @@ * An abstract EIP-1193 provider wired to some duplex stream via a

/**
* @param connectionStream - A Node.js duplex stream
* @param options - An options bag
* Creates a new AbstractStreamProvider instance.
*
* @param connectionStream - A Node.js duplex stream.
* @param options - An options bag.
* @param options.jsonRpcStreamName - The name of the internal JSON-RPC stream.
* @param options.logger - The logging API to use. Default: console
* @param options.logger - The logging API to use. Default: `console`.
* @param options.maxEventListeners - The maximum number of event
* listeners. Default: 100
* listeners. Default: 100.
* @param options.rpcMiddleware - The RPC middleware stack to use.
*/
constructor(connectionStream: Duplex, { jsonRpcStreamName, logger, maxEventListeners, rpcMiddleware, }: StreamProviderOptions);
/**
* **MUST** be called by child classes.
* MUST be called by child classes.
*

@@ -48,3 +51,6 @@ * Calls `metamask_getProviderState` and passes the result to

*
* @emits BaseProvider#disconnect
* @param streamName - The name of the stream that disconnected.
* @param error - The error that caused the disconnection.
* @fires BaseProvider#disconnect - If the provider is not already
* disconnected.
*/

@@ -61,3 +67,3 @@ private _handleStreamDisconnect;

*
* @emits BaseProvider#chainChanged
* @fires BaseProvider#chainChanged
* @param networkInfo - An object with network info.

@@ -68,4 +74,4 @@ * @param networkInfo.chainId - The latest chain ID.

protected _handleChainChanged({ chainId, networkVersion, }?: {
chainId?: string;
networkVersion?: string;
chainId?: string | undefined;
networkVersion?: string | undefined;
}): void;

@@ -81,3 +87,3 @@ }

/**
* **MUST** be called after instantiation to complete initialization.
* MUST be called after instantiation to complete initialization.
*

@@ -84,0 +90,0 @@ * Calls `metamask_getProviderState` and passes the result to

@@ -11,5 +11,5 @@ "use strict";

const pump_1 = __importDefault(require("pump"));
const BaseProvider_1 = require("./BaseProvider");
const messages_1 = __importDefault(require("./messages"));
const utils_1 = require("./utils");
const BaseProvider_1 = require("./BaseProvider");
/**

@@ -23,12 +23,15 @@ * An abstract EIP-1193 provider wired to some duplex stream via a

/**
* @param connectionStream - A Node.js duplex stream
* @param options - An options bag
* Creates a new AbstractStreamProvider instance.
*
* @param connectionStream - A Node.js duplex stream.
* @param options - An options bag.
* @param options.jsonRpcStreamName - The name of the internal JSON-RPC stream.
* @param options.logger - The logging API to use. Default: console
* @param options.logger - The logging API to use. Default: `console`.
* @param options.maxEventListeners - The maximum number of event
* listeners. Default: 100
* listeners. Default: 100.
* @param options.rpcMiddleware - The RPC middleware stack to use.
*/
constructor(connectionStream, { jsonRpcStreamName, logger, maxEventListeners, rpcMiddleware, }) {
constructor(connectionStream, { jsonRpcStreamName, logger = console, maxEventListeners = 100, rpcMiddleware = [], }) {
super({ logger, maxEventListeners, rpcMiddleware });
if (!is_stream_1.duplex(connectionStream)) {
if (!(0, is_stream_1.duplex)(connectionStream)) {
throw new Error(messages_1.default.errors.invalidDuplexStream());

@@ -40,8 +43,10 @@ }

const mux = new object_multiplex_1.default();
pump_1.default(connectionStream, mux, connectionStream, this._handleStreamDisconnect.bind(this, 'MetaMask'));
(0, pump_1.default)(connectionStream, mux, connectionStream, this._handleStreamDisconnect.bind(this, 'MetaMask'));
// Set up RPC connection
this._jsonRpcConnection = json_rpc_middleware_stream_1.createStreamMiddleware({
// Typecast: The type of `Duplex` is incompatible with the type of
// `JsonRpcConnection`.
this._jsonRpcConnection = (0, json_rpc_middleware_stream_1.createStreamMiddleware)({
retryOnMessage: 'METAMASK_EXTENSION_CONNECT_CAN_RETRY',
});
pump_1.default(this._jsonRpcConnection.stream, mux.createStream(jsonRpcStreamName), this._jsonRpcConnection.stream, this._handleStreamDisconnect.bind(this, 'MetaMask RpcProvider'));
(0, pump_1.default)(this._jsonRpcConnection.stream, mux.createStream(jsonRpcStreamName), this._jsonRpcConnection.stream, this._handleStreamDisconnect.bind(this, 'MetaMask RpcProvider'));
// Wire up the JsonRpcEngine to the JSON-RPC connection stream

@@ -76,3 +81,3 @@ this._rpcEngine.push(this._jsonRpcConnection.middleware);

/**
* **MUST** be called by child classes.
* MUST be called by child classes.
*

@@ -99,7 +104,11 @@ * Calls `metamask_getProviderState` and passes the result to

*
* @emits BaseProvider#disconnect
* @param streamName - The name of the stream that disconnected.
* @param error - The error that caused the disconnection.
* @fires BaseProvider#disconnect - If the provider is not already
* disconnected.
*/
// eslint-disable-next-line no-restricted-syntax
_handleStreamDisconnect(streamName, error) {
let warningMsg = `MetaMask: Lost connection to "${streamName}".`;
if (error === null || error === void 0 ? void 0 : error.stack) {
if (error?.stack) {
warningMsg += `\n${error.stack}`;

@@ -122,3 +131,3 @@ }

*
* @emits BaseProvider#chainChanged
* @fires BaseProvider#chainChanged
* @param networkInfo - An object with network info.

@@ -129,3 +138,3 @@ * @param networkInfo.chainId - The latest chain ID.

_handleChainChanged({ chainId, networkVersion, } = {}) {
if (!utils_1.isValidChainId(chainId) || !utils_1.isValidNetworkVersion(networkVersion)) {
if (!(0, utils_1.isValidChainId)(chainId) || !(0, utils_1.isValidNetworkVersion)(networkVersion)) {
this._log.error(messages_1.default.errors.invalidNetworkParams(), {

@@ -154,3 +163,3 @@ chainId,

/**
* **MUST** be called after instantiation to complete initialization.
* MUST be called after instantiation to complete initialization.
*

@@ -157,0 +166,0 @@ * Calls `metamask_getProviderState` and passes the result to

@@ -13,3 +13,3 @@ import { JsonRpcMiddleware, PendingJsonRpcResponse } from 'json-rpc-engine';

export declare const getDefaultExternalMiddleware: (logger?: ConsoleLike) => JsonRpcMiddleware<unknown, unknown>[];
export declare const getRpcPromiseCallback: (resolve: (value?: any) => void, reject: (error?: Error | undefined) => void, unwrapResult?: boolean) => (error: Error, response: PendingJsonRpcResponse<unknown>) => void;
export declare const getRpcPromiseCallback: (resolve: (value?: any) => void, reject: (error?: Error) => void, unwrapResult?: boolean) => (error: Error, response: PendingJsonRpcResponse<unknown>) => void;
/**

@@ -16,0 +16,0 @@ * Checks whether the given chain ID is valid, meaning if it is non-empty,

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NOOP = exports.isValidNetworkVersion = exports.isValidChainId = exports.getRpcPromiseCallback = exports.getDefaultExternalMiddleware = exports.EMITTED_NOTIFICATIONS = void 0;
const eth_rpc_errors_1 = require("eth-rpc-errors");
const json_rpc_engine_1 = require("json-rpc-engine");
const eth_rpc_errors_1 = require("eth-rpc-errors");
const createRpcWarningMiddleware_1 = require("./middleware/createRpcWarningMiddleware");

@@ -20,9 +20,10 @@ // Constants

const getDefaultExternalMiddleware = (logger = console) => [
json_rpc_engine_1.createIdRemapMiddleware(),
(0, json_rpc_engine_1.createIdRemapMiddleware)(),
createErrorMiddleware(logger),
createRpcWarningMiddleware_1.createRpcWarningMiddleware(logger),
(0, createRpcWarningMiddleware_1.createRpcWarningMiddleware)(logger),
];
exports.getDefaultExternalMiddleware = getDefaultExternalMiddleware;
/**
* json-rpc-engine middleware that logs RPC errors and and validates req.method.
* A `json-rpc-engine` middleware that logs RPC errors and validates the request
* method.
*

@@ -33,12 +34,12 @@ * @param log - The logging API to use.

function createErrorMiddleware(log) {
return (req, res, next) => {
return (request, response, next) => {
// json-rpc-engine will terminate the request when it notices this error
if (typeof req.method !== 'string' || !req.method) {
res.error = eth_rpc_errors_1.ethErrors.rpc.invalidRequest({
if (typeof request.method !== 'string' || !request.method) {
response.error = eth_rpc_errors_1.ethErrors.rpc.invalidRequest({
message: `The request 'method' must be a non-empty string.`,
data: req,
data: request,
});
}
next((done) => {
const { error } = res;
const { error } = response;
if (!error) {

@@ -45,0 +46,0 @@ return done();

{
"name": "@metamask/providers",
"version": "10.2.1",
"version": "11.0.0",
"description": "A JavaScript Ethereum provider that connects to the wallet over a stream.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=14.0.0"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"setup": "yarn install && yarn allow-scripts",
"build": "mkdir -p dist && rm -rf dist/* && tsc --project .",
"test": "jest && jest-it-up",
"test:watch": "yarn test --watch",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --single-quote --ignore-path .gitignore",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"prepublishOnly": "yarn build && yarn lint && yarn test"
},
"author": "MetaMask",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/MetaMask/providers.git"
},
"keywords": [

@@ -36,13 +10,34 @@ "MetaMask",

],
"homepage": "https://github.com/MetaMask/providers#readme",
"bugs": {
"url": "https://github.com/MetaMask/providers/issues"
},
"homepage": "https://github.com/MetaMask/providers#readme",
"repository": {
"type": "git",
"url": "https://github.com/MetaMask/providers.git"
},
"license": "MIT",
"author": "MetaMask",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist/"
],
"scripts": {
"build": "tsc --project tsconfig.build.json",
"build:clean": "rimraf dist && yarn build",
"build:docs": "typedoc",
"lint": "yarn lint:eslint && yarn lint:misc --check && yarn lint:dependencies --check && yarn lint:changelog",
"lint:changelog": "auto-changelog validate",
"lint:dependencies": "depcheck && yarn dedupe",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write && yarn lint:dependencies && yarn lint:changelog",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
"prepack": "./scripts/prepack.sh",
"test": "jest && jest-it-up",
"test:watch": "jest --watch"
},
"dependencies": {
"@metamask/object-multiplex": "^1.1.0",
"@metamask/safe-event-emitter": "^2.0.0",
"@types/chrome": "^0.0.136",
"@metamask/safe-event-emitter": "^3.0.0",
"detect-browser": "^5.2.0",

@@ -56,34 +51,50 @@ "eth-rpc-errors": "^4.0.2",

"pump": "^3.0.0",
"webextension-polyfill-ts": "^0.25.0"
"webextension-polyfill": "^0.10.0"
},
"devDependencies": {
"@lavamoat/allow-scripts": "^2.0.3",
"@metamask/auto-changelog": "^3.0.0",
"@metamask/eslint-config": "^7.0.1",
"@metamask/eslint-config-jest": "^7.0.0",
"@metamask/eslint-config-nodejs": "^7.0.1",
"@metamask/eslint-config-typescript": "^7.0.1",
"@types/jest": "^26.0.23",
"@types/node": "^14.14.14",
"@metamask/auto-changelog": "^3.1.0",
"@metamask/eslint-config": "^11.0.1",
"@metamask/eslint-config-jest": "^11.0.0",
"@metamask/eslint-config-nodejs": "^11.0.1",
"@metamask/eslint-config-typescript": "^11.0.0",
"@types/chrome": "^0.0.233",
"@types/jest": "^28.1.6",
"@types/node": "^17.0.23",
"@types/pump": "^1.1.0",
"@types/readable-stream": "^2.3.9",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
"eslint": "^7.29.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jest": "^23.18.0",
"eslint-plugin-json": "^2.0.1",
"@types/readable-stream": "^2.3.15",
"@types/webextension-polyfill": "^0.10.0",
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
"depcheck": "^1.4.3",
"eslint": "^8.27.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^27.1.5",
"eslint-plugin-jsdoc": "^39.6.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"jest": "^26.6.3",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^28.1.3",
"jest-chrome": "^0.7.1",
"jest-environment-jsdom": "^29.5.0",
"jest-it-up": "^2.0.2",
"prettier": "^2.3.1",
"ts-jest": "^26.5.6",
"typescript": "^4.3.5"
"prettier": "^2.7.1",
"prettier-plugin-packagejson": "^2.3.0",
"rimraf": "^3.0.2",
"ts-jest": "^28.0.7",
"ts-node": "^10.7.0",
"typedoc": "^0.23.15",
"typescript": "~4.8.4"
},
"packageManager": "yarn@3.2.1",
"engines": {
"node": ">=16.0.0"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"lavamoat": {
"allowScripts": {}
}
}
}

@@ -44,3 +44,3 @@ # MetaMask Providers

- Install [Node.js](https://nodejs.org) version 14
- Install [Node.js](https://nodejs.org) version 16
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.

@@ -47,0 +47,0 @@ - Install [Yarn v1](https://yarnpkg.com/en/docs/install)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc