eth-json-rpc-filters/test/util.js

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,
}
}