# web3-provider-engine

> A JavaScript library for composing Ethereum provider objects using middleware modules

Latest version **17.0.1** (published 2024-04-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install web3-provider-engine
pnpm add web3-provider-engine
yarn add web3-provider-engine
bun add web3-provider-engine
```

## Health

**Score 23/100 (F)** — status: abandoned.

Positive: has types package; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 17.0.1 |
| Published | 2024-04-22 |
| First published | 2015-12-19 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | separate (@types/web3-provider-engine) |
| Module format | CommonJS |
| Node | ^16.20 \|\| ^18.16 \|\| >=20 |
| Dependencies | 22 |
| Unpacked size | 4 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 601 |
| Maintainers | mcmire, nicholasellul, lgbot, naugtur, ritave, danfinlay, kumavis, rekmarks, metamaskbot, gudahtt, brad.decker, sethkfman |

## Links

- npm: https://www.npmjs.com/package/web3-provider-engine
- Repository: https://github.com/MetaMask/web3-provider-engine
- Homepage: https://github.com/MetaMask/web3-provider-engine#readme
- Issues: https://github.com/MetaMask/web3-provider-engine/issues
- npm.io page: https://npm.io/package/web3-provider-engine

## Dependencies (22)

- [ws](https://npm.io/package/ws.md) ^7.5.9
- [xhr](https://npm.io/package/xhr.md) ^2.6.0
- [async](https://npm.io/package/async.md) ^2.6.4
- [clone](https://npm.io/package/clone.md) ^2.1.2
- [xtend](https://npm.io/package/xtend.md) ^4.0.2
- [backoff](https://npm.io/package/backoff.md) ^2.5.0
- [semaphore](https://npm.io/package/semaphore.md) ^1.1.0
- [@ethereumjs/tx](https://npm.io/package/@ethereumjs/tx.md) ^4.2.0
- [@ethereumjs/vm](https://npm.io/package/@ethereumjs/vm.md) ^6.5.0
- [readable-stream](https://npm.io/package/readable-stream.md) ^3.6.2
- [@cypress/request](https://npm.io/package/@cypress/request.md) ^3.0.1
- [@ethereumjs/util](https://npm.io/package/@ethereumjs/util.md) ^8.1.0
- [@ethereumjs/block](https://npm.io/package/@ethereumjs/block.md) ^4.3.0
- [eth-block-tracker](https://npm.io/package/eth-block-tracker.md) ^8.1.0
- [promise-to-callback](https://npm.io/package/promise-to-callback.md) ^1.0.0
- [@metamask/rpc-errors](https://npm.io/package/@metamask/rpc-errors.md) ^6.2.1
- [json-stable-stringify](https://npm.io/package/json-stable-stringify.md) ^1.1.1
- [@metamask/eth-sig-util](https://npm.io/package/@metamask/eth-sig-util.md) ^7.0.1
- [@ethereumjs/statemanager](https://npm.io/package/@ethereumjs/statemanager.md) ^1.1.0
- [@metamask/eth-json-rpc-infura](https://npm.io/package/@metamask/eth-json-rpc-infura.md) ^9.1.0
- [@metamask/eth-json-rpc-filters](https://npm.io/package/@metamask/eth-json-rpc-filters.md) ^7.0.0
- [@metamask/eth-json-rpc-middleware](https://npm.io/package/@metamask/eth-json-rpc-middleware.md) ^12.1.0

## Recent versions

- 17.0.1 (latest) — 2024-04-22
- 16.0.8 — 2024-04-22
- 17.0.0 — 2024-04-18
- 16.0.7 — 2023-10-23
- 16.0.6 — 2023-10-13
- 16.0.5 — 2023-01-04
- 16.0.4 — 2022-04-29
- 16.0.3 — 2021-07-15
- 16.0.2 — 2021-07-15
- 16.0.1 — 2020-09-23
- 16.0.0 — 2020-09-23
- 15.0.12 — 2020-05-28
- 15.0.11 — 2020-05-28
- 15.0.10 — 2020-05-28
- 15.0.9 — 2020-05-26
- … 177 more at https://npm.io/package/web3-provider-engine/versions

## README

# Web3 ProviderEngine

Web3 ProviderEngine is a tool for composing your own [web3 providers](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3).

> [!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:
>
> ```javascript
> 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.

```js
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:
```js
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](https://github.com/ethereum/wiki/wiki/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

```bash
yarn test
```

---
_Source: https://npm.io/package/web3-provider-engine · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
