https://github.com/MetaMask/web3-provider-engine
A JavaScript library for composing Ethereum provider objects using middleware modules
https://github.com/MetaMask/web3-provider-engine
Last synced: 10 months ago
JSON representation
A JavaScript library for composing Ethereum provider objects using middleware modules
- Host: GitHub
- URL: https://github.com/MetaMask/web3-provider-engine
- Owner: MetaMask
- License: mit
- Archived: true
- Created: 2015-12-09T00:32:36.000Z (about 10 years ago)
- Default Branch: main
- Last Pushed: 2024-04-22T08:27:27.000Z (almost 2 years ago)
- Last Synced: 2024-10-14T13:02:40.904Z (over 1 year ago)
- Language: JavaScript
- Homepage:
- Size: 5.29 MB
- Stars: 598
- Watchers: 72
- Forks: 328
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
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
```