Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

web3-provider-engine

MetaMask517.4kMIT17.0.1TypeScript support: definitely-typed

A JavaScript library for composing Ethereum provider objects using middleware modules

readme

Web3 ProviderEngine

Web3 ProviderEngine is a tool for composing your own web3 providers.

[!CAUTION] This package has been deprecated.

This package was originally created for MetaMask, but has been replaced by @metamask/json-rpc-engine, @metamask/eth-json-rpc-middleware, @metamask/eth-json-rpc-provider, and various other packages.

Here is an example of how to create a provider using those packages:

import { providerFromMiddleware } from '@metamask/eth-json-rpc-provider';
import { createFetchMiddleware } from '@metamask/eth-json-rpc-middleware';
import { valueToBytes, bytesToBase64 } from '@metamask/utils';
import fetch from 'cross-fetch';

const rpcUrl = '[insert RPC URL here]';

const fetchMiddleware = createFetchMiddleware({
  btoa: (stringToEncode) => bytesToBase64(valueToBytes(stringToEncode)),
  fetch,
  rpcUrl,
});
const provider = providerFromMiddleware(fetchMiddleware);

provider.sendAsync(
  { id: 1, jsonrpc: '2.0', method: 'eth_chainId' },
  (error, response) => {
    if (error) {
      console.error(error);
    } else {
      console.log(response.result);
    }
  }
);

This example was written with v12.1.0 of @metamask/eth-json-rpc-middleware, v3.0.1 of @metamask/eth-json-rpc-provider, and v8.4.0 of @metamask/utils.

Composable

Built to be modular - works via a stack of 'sub-providers' which are like normal web3 providers but only handle a subset of rpc methods.

The subproviders can emit new rpc requests in order to handle their own; e.g. eth_call may trigger eth_getAccountBalance, eth_getCode, and others. The provider engine also handles caching of rpc request results.

const ProviderEngine = require('web3-provider-engine')
const CacheSubprovider = require('web3-provider-engine/subproviders/cache.js')
const FixtureSubprovider = require('web3-provider-engine/subproviders/fixture.js')
const FilterSubprovider = require('web3-provider-engine/subproviders/filters.js')
const VmSubprovider = require('web3-provider-engine/subproviders/vm.js')
const HookedWalletSubprovider = require('web3-provider-engine/subproviders/hooked-wallet.js')
const NonceSubprovider = require('web3-provider-engine/subproviders/nonce-tracker.js')
const RpcSubprovider = require('web3-provider-engine/subproviders/rpc.js')

var engine = new ProviderEngine()
var web3 = new Web3(engine)

// static results
engine.addProvider(new FixtureSubprovider({
  web3_clientVersion: 'ProviderEngine/v0.0.0/javascript',
  net_listening: true,
  eth_hashrate: '0x00',
  eth_mining: false,
  eth_syncing: true,
}))

// cache layer
engine.addProvider(new CacheSubprovider())

// filters
engine.addProvider(new FilterSubprovider())

// pending nonce
engine.addProvider(new NonceSubprovider())

// vm
engine.addProvider(new VmSubprovider())

// id mgmt
engine.addProvider(new HookedWalletSubprovider({
  getAccounts: function(cb){ ... },
  approveTransaction: function(cb){ ... },
  signTransaction: function(cb){ ... },
}))

// data source
engine.addProvider(new RpcSubprovider({
  rpcUrl: 'https://testrpc.metamask.io/',
}))

// log new blocks
engine.on('block', function(block){
  console.log('================================')
  console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex'))
  console.log('================================')
})

// network connectivity error
engine.on('error', function(err){
  // report connectivity errors
  console.error(err.stack)
})

// start polling for blocks
engine.start()

When importing in webpack:

import * as Web3ProviderEngine  from 'web3-provider-engine';
import * as RpcSource  from 'web3-provider-engine/subproviders/rpc';
import * as HookedWalletSubprovider from 'web3-provider-engine/subproviders/hooked-wallet';

Built For Zero-Clients

The Ethereum JSON RPC was not designed to have one node service many clients. However a smaller, lighter subset of the JSON RPC can be used to provide the blockchain data that an Ethereum 'zero-client' node would need to function. We handle as many types of requests locally as possible, and just let data lookups fallback to some data source ( hosted rpc, blockchain api, etc ). Categorically, we don’t want / can’t have the following types of RPC calls go to the network:

  • id mgmt + tx signing (requires private data)
  • filters (requires a stateful data api)
  • vm (expensive, hard to scale)

Running tests

yarn test

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

[17.0.1]

Fixed

  • Properly return signed transaction object in signTransaction of HookedWalletEthTxSubprovider (#465)

[16.0.8]

Changed

  • Update dependencies (#477)
    • eth-rpc-errors@^3.0.0->^4.0.3
    • ethereumjs-block@^1.2.2->^2.2.2
    • ethereumjs-util@^5.1.5->^7.1.5
    • ethereumjs-vm@^2.3.4->^2.6.0
    • eth-json-rpc-filters@^4.2.1->~5.0.0
    • eth-json-rpc-infura@^5.1.0 -> @metamask/eth-json-rpc-infura@^6.0.0
    • eth-json-rpc-middleware@^6.0.0->^8.1.0
    • eth-sig-util@^1.4.2 -> @metamask/eth-sig-util@^4.0.1

Fixed

  • Properly return signed transaction object in signTransaction of HookedWalletEthTxSubprovider (#465)

[17.0.0]

Changed

  • Add deprecation notice (#469)
  • BREAKING: Increase minimum Node.js version to 16 (#447)
  • Bump ethereumjs and metamask dependencies (#453) (#471)
  • babelify dependencies (#454)
  • Update dependency readable-stream from ^2.2.9 to ^3.6.2 (#452)
  • Update devDependency browserify from 16.5.0 to 17.0.0 (#456)

[16.0.7]

Fixed

  • Properly replace vulnerable dependency request with patched @cypress/request (#459)

[16.0.6]

Fixed

  • Replace vulnerable dependency request with patched @cypress/request (#441)
  • Update ws from ^5.1.1 to ^7.5.9 (#446)

[16.0.5]

Changed

  • Update eth-block-tracker to 5.0.1 to remove unintentional dependency on Babel, which produced warning locally when not installed (#409)

[16.0.4] - 2022-04-29

Fixed

  • Remove vulnerable version of cross-fetch (#404)

[16.0.3] - 2021-07-15

Changed

  • Remove zero prefix from address. (#380)
    • The previously published version v16.0.2 (now deprecated) included an upgrade that didn't take into account that tx.getSenderAddress().toString('hex') now includes the leading 0x prefix.

[16.0.2] - 2021-07-14

Changed

  • Update ethereumjs-tx to @ethereumjs/tx to support EIP1559 transactions (#356)

16.0.1 - 2020-09-23

Changed

  • Fix broken publish files (#356)

[16.0.0] - 2020-09-22

Changed

[15.0.0]

Changed

  • uses eth-block-tracker@4, but still provides block body on ('block', 'latest', and 'rawBlock'). Other events ('sync') provide block number hex string instead of block body.
  • SubscriptionsSubprovider automatically forwards events to provider
  • replacing subprovider implementations with those in eth-json-rpc-engine
  • browserify: moved to babelify@10 + @babel/core@7

[14.0.0]

Changed

  • default dataProvider for zero is Infura mainnet REST api
  • websocket support
  • subscriptions support
  • remove solc subprovider
  • removed dist from git (but published in npm module)
  • es5 builds in dist/es5
  • zero + ProviderEngine bundles are es5
  • web3 subprovider renamed to provider subprovider
  • error if provider subprovider is missing a proper provider
  • removed need to supply getAccounts hook
  • fixed hooked-wallet-ethtx message signing
  • fixed hooked-wallet default txParams

[13.0.0]

Changed

[12.0.0]

Changed

[11.0.0]

Changed

  • zero.js - replaced http subprovider with fetch provider (includes polyfill for node).

[10.0.0]

Changed

  • renamed HookedWalletSubprovider personalRecoverSigner to recoverPersonalSignature

[9.0.0]

Changed

  • pollingShouldUnref option now defaults to false