151 lines
4.6 KiB
JavaScript
151 lines
4.6 KiB
JavaScript
const EventEmitter = require('events')
|
|
const EthBlockTracker = require('eth-block-tracker')
|
|
const EthQuery = require('ethjs-query')
|
|
const JsonRpcEngine = require('json-rpc-engine')
|
|
const providerAsMiddleware = require('eth-json-rpc-middleware/providerAsMiddleware')
|
|
const providerFromEngine = require('eth-json-rpc-middleware/providerFromEngine')
|
|
const GanacheCore = require('ganache-core')
|
|
const pify = require('pify')
|
|
const createFilterMiddleware = require('../index.js')
|
|
const createSubscriptionMiddleware = require('../subscriptionManager.js')
|
|
|
|
module.exports = {
|
|
createPayload,
|
|
createEngineFromGanacheCore,
|
|
createEngineFromTestBlockMiddleware,
|
|
createTestSetup,
|
|
asyncTest,
|
|
timeout,
|
|
deployLogEchoContract,
|
|
}
|
|
|
|
function createTestSetup () {
|
|
// raw data source
|
|
const { ganacheProvider, forceNextBlock } = createEngineFromGanacheCore()
|
|
// create block trackerfilterId
|
|
const blockTracker = new EthBlockTracker({
|
|
provider: ganacheProvider,
|
|
pollingInterval: 200,
|
|
})
|
|
// create higher level
|
|
const engine = new JsonRpcEngine()
|
|
const provider = providerFromEngine(engine)
|
|
const query = new EthQuery(provider)
|
|
// add filter middleware
|
|
engine.push(createFilterMiddleware({ blockTracker, provider }))
|
|
// add subscription middleware
|
|
const subscriptionManager = createSubscriptionMiddleware({ blockTracker, provider })
|
|
engine.push(subscriptionManager.middleware)
|
|
subscriptionManager.events.on('notification', (message) => engine.emit('notification', message))
|
|
// add data source
|
|
engine.push(providerAsMiddleware(ganacheProvider))
|
|
|
|
// subs helper
|
|
const subs = createSubsHelper({ provider })
|
|
|
|
return { ganacheProvider, forceNextBlock, engine, provider, query, subs, blockTracker, trackNextBlock }
|
|
|
|
async function trackNextBlock() {
|
|
return new Promise((resolve) => blockTracker.once('latest', resolve))
|
|
}
|
|
}
|
|
|
|
function createSubsHelper({ provider }) {
|
|
return {
|
|
logs: createSubGenerator({ subType: 'logs', provider }),
|
|
newPendingTransactions: createSubGenerator({ subType: 'newPendingTransactions', provider }),
|
|
newHeads: createSubGenerator({ subType: 'newHeads', provider }),
|
|
}
|
|
}
|
|
|
|
function createSubGenerator({ subType, provider }) {
|
|
return pify(function() {
|
|
const args = [].slice.call(arguments)
|
|
const cb = args.pop()
|
|
args.unshift(subType)
|
|
provider.sendAsync({ method: 'eth_subscribe', params: args }, (err, res) => {
|
|
if (err) return cb(err)
|
|
const id = res.result
|
|
const result = createNewSub({ id, provider })
|
|
cb(null, result)
|
|
})
|
|
})
|
|
}
|
|
|
|
function createNewSub({ id, provider }) {
|
|
// event emitter for emiting subscription hits
|
|
const events = new EventEmitter()
|
|
// filter rpc notifications for matching subscription
|
|
provider.on('data', (_, message) => {
|
|
if (message.method !== 'eth_subscription') return
|
|
const subId = message.params.subscription
|
|
if (subId !== id) return
|
|
const value = message.params.result
|
|
events.emit('notification', value)
|
|
})
|
|
// subscription uninstall method
|
|
function uninstall(cb) {
|
|
provider.sendAsync({ method: 'eth_unsubscribe', params: [id] }, (err, res) => {
|
|
if (err) return cb(err)
|
|
cb(null, res.result)
|
|
})
|
|
}
|
|
// return custom "subscription" api object
|
|
return {
|
|
id,
|
|
events,
|
|
uninstall: pify(uninstall),
|
|
}
|
|
}
|
|
|
|
function createEngineFromGanacheCore () {
|
|
const ganacheProvider = GanacheCore.provider()
|
|
return { ganacheProvider, forceNextBlock }
|
|
|
|
async function forceNextBlock() {
|
|
// custom ganache-core method
|
|
await pify(ganacheProvider.sendAsync).call(ganacheProvider, createPayload({ method: 'evm_mine' }))
|
|
}
|
|
}
|
|
|
|
function createEngineFromTestBlockMiddleware () {
|
|
const engine = new JsonRpcEngine()
|
|
const testBlockSource = new TestBlockMiddleware()
|
|
engine.push(testBlockSource.createMiddleware())
|
|
return { engine, testBlockSource }
|
|
}
|
|
|
|
function createPayload(payload) {
|
|
return Object.assign({ id: 1, jsonrpc: '2.0', params: [] }, payload)
|
|
}
|
|
|
|
function asyncTest(asyncTestFn){
|
|
return async function(t) {
|
|
try {
|
|
await asyncTestFn(t)
|
|
t.end()
|
|
} catch (err) {
|
|
t.end(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
function timeout(duration) {
|
|
return new Promise(resolve => setTimeout(resolve, duration))
|
|
}
|
|
|
|
|
|
async function deployLogEchoContract({ tools, from }){
|
|
// https://github.com/kumavis/eth-needlepoint/blob/master/examples/emit-log.js
|
|
const eth = tools.query
|
|
const deployTxHash = await eth.sendTransaction({ from, data: '0x600e600c600039600e6000f336600060003760005160206000a1' })
|
|
await tools.trackNextBlock()
|
|
const deployTxRx = await eth.getTransactionReceipt(deployTxHash)
|
|
const contractAddress = deployTxRx.contractAddress
|
|
return {
|
|
deployTxHash,
|
|
deployTxRx,
|
|
contractAddress,
|
|
}
|
|
}
|