@bitski/provider-engine
Advanced tools
Comparing version 0.2.0-beta.4 to 0.2.0-beta.5
{ | ||
"name": "@bitski/provider-engine", | ||
"version": "0.2.0-beta.4", | ||
"version": "0.2.0-beta.5", | ||
"description": "", | ||
"repository": "https://github.com/BitskiCo/provider-engine", | ||
"main": "dist/es6/index.js", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"test": "ts-node node_modules/tape/bin/tape test/index.ts", | ||
"prepublish": "npm run build", | ||
"build": "tsc && babel dist/es6 -d dist/es5" | ||
"build": "tsc" | ||
}, | ||
@@ -12,0 +12,0 @@ "author": "", |
196
src/index.ts
@@ -1,194 +0,4 @@ | ||
import * as eachSeries from 'async/eachSeries'; | ||
import * as map from 'async/map'; | ||
import * as PollingBlockTracker from 'eth-block-tracker'; | ||
import { EventEmitter } from 'events'; | ||
import { createPayload } from './util/create-payload'; | ||
import { toBuffer } from './util/eth-util'; | ||
import Stoplight from './util/stoplight'; | ||
import Web3ProviderEngine from './provider-engine'; | ||
export default class Web3ProviderEngine extends EventEmitter { | ||
public _blockTracker: PollingBlockTracker; | ||
public _ready: Stoplight; | ||
public currentBlock: any; | ||
public currentBlockNumber: any; | ||
public _providers: any[]; | ||
constructor(opts?) { | ||
super(); | ||
this.setMaxListeners(30); | ||
// parse options | ||
opts = opts || {}; | ||
// block polling | ||
const directProvider = { | ||
sendAsync: (payload, callback) => { | ||
payload.skipCache = true; | ||
this._handleAsync(payload, callback); | ||
}, | ||
}; | ||
const blockTrackerProvider = opts.blockTrackerProvider || directProvider; | ||
this._blockTracker = opts.blockTracker || new PollingBlockTracker({ | ||
provider: blockTrackerProvider, | ||
pollingInterval: opts.pollingInterval || 4000, | ||
}); | ||
// set initialization blocker | ||
this._ready = new Stoplight(); | ||
// local state | ||
this.currentBlock = null; | ||
this._providers = []; | ||
} | ||
public start() { | ||
// handle new block | ||
this._blockTracker.on('latest', (blockNumber) => { | ||
this._setCurrentBlockNumber(blockNumber); | ||
}); | ||
// emit block events from the block tracker | ||
this._blockTracker.on('sync', this.emit.bind(this, 'sync')); | ||
this._blockTracker.on('latest', this.emit.bind(this, 'latest')); | ||
// unblock initialization after first block | ||
this._blockTracker.once('latest', () => { | ||
this._ready.go(); | ||
}); | ||
} | ||
public stop() { | ||
// stop block polling | ||
this._blockTracker.removeAllListeners(); | ||
} | ||
public addProvider(source) { | ||
this._providers.push(source); | ||
source.setEngine(this); | ||
} | ||
public send(payload) { | ||
throw new Error('Web3ProviderEngine does not support synchronous requests.'); | ||
} | ||
public sendAsync(payload, cb) { | ||
this._ready.await(() => { | ||
if (Array.isArray(payload)) { | ||
// handle batch | ||
map(payload, this._handleAsync.bind(this), cb); | ||
} else { | ||
// handle single | ||
this._handleAsync(payload, cb); | ||
} | ||
}); | ||
} | ||
public _handleAsync(payload, finished) { | ||
let currentProvider = -1; | ||
let result = null; | ||
let error = null; | ||
const stack = []; | ||
const next = (after?) => { | ||
currentProvider += 1; | ||
stack.unshift(after); | ||
// Bubbled down as far as we could go, and the request wasn't | ||
// handled. Return an error. | ||
if (currentProvider >= this._providers.length) { | ||
// tslint:disable-next-line: max-line-length | ||
const msg = `Request for method "${payload.method}" not handled by any subprovider. Please check your subprovider configuration to ensure this method is handled.`; | ||
end(new Error(msg)); | ||
} else { | ||
try { | ||
const provider = this._providers[currentProvider]; | ||
provider.handleRequest(payload, next, end); | ||
} catch (e) { | ||
end(e); | ||
} | ||
} | ||
}; | ||
const end = (_error: Error | undefined, _result: any | undefined = undefined) => { | ||
error = _error; | ||
result = _result; | ||
eachSeries(stack, (fn, callback) => { | ||
if (fn) { | ||
fn(error, result, callback); | ||
} else { | ||
callback(); | ||
} | ||
}, () => { | ||
// console.log('COMPLETED:', payload) | ||
// console.log('RESULT: ', result) | ||
const resultObj: any = { | ||
id: payload.id, | ||
jsonrpc: payload.jsonrpc, | ||
result, | ||
}; | ||
if (error != null) { | ||
resultObj.error = { | ||
message: error.stack || error.message || error, | ||
code: -32000, | ||
}; | ||
// respond with both error formats | ||
finished(error, resultObj); | ||
} else { | ||
finished(null, resultObj); | ||
} | ||
}); | ||
}; | ||
next(); | ||
} | ||
// Once we detect a new block number, load the block data | ||
public _setCurrentBlockNumber(blockNumber) { | ||
const self = this; | ||
self.currentBlockNumber = blockNumber; | ||
// Make sure we skip the cache for this request | ||
const payload = createPayload({ method: 'eth_getBlockByNumber', params: [blockNumber, false], skipCache: true }); | ||
self.sendAsync(payload, (err, result) => { | ||
if (err) { return; } | ||
const bufferBlock = toBufferBlock(result.result); | ||
self._setCurrentBlock(bufferBlock); | ||
}); | ||
} | ||
public _setCurrentBlock(block) { | ||
const self = this; | ||
self.currentBlock = block; | ||
self.emit('block', block); | ||
} | ||
} | ||
// util | ||
function toBufferBlock(jsonBlock) { | ||
return { | ||
number: toBuffer(jsonBlock.number), | ||
hash: toBuffer(jsonBlock.hash), | ||
parentHash: toBuffer(jsonBlock.parentHash), | ||
nonce: toBuffer(jsonBlock.nonce), | ||
mixHash: toBuffer(jsonBlock.mixHash), | ||
sha3Uncles: toBuffer(jsonBlock.sha3Uncles), | ||
logsBloom: toBuffer(jsonBlock.logsBloom), | ||
transactionsRoot: toBuffer(jsonBlock.transactionsRoot), | ||
stateRoot: toBuffer(jsonBlock.stateRoot), | ||
receiptsRoot: toBuffer(jsonBlock.receiptRoot || jsonBlock.receiptsRoot), | ||
miner: toBuffer(jsonBlock.miner), | ||
difficulty: toBuffer(jsonBlock.difficulty), | ||
totalDifficulty: toBuffer(jsonBlock.totalDifficulty), | ||
size: toBuffer(jsonBlock.size), | ||
extraData: toBuffer(jsonBlock.extraData), | ||
gasLimit: toBuffer(jsonBlock.gasLimit), | ||
gasUsed: toBuffer(jsonBlock.gasUsed), | ||
timestamp: toBuffer(jsonBlock.timestamp), | ||
transactions: jsonBlock.transactions, | ||
}; | ||
} | ||
export default Web3ProviderEngine; | ||
export * from './subproviders/index'; |
{ | ||
"compilerOptions": { | ||
"outDir": "./dist/es6", | ||
"outDir": "./dist", | ||
"target": "es6", | ||
@@ -5,0 +5,0 @@ "declaration": true, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
1
189974
113
5108