ethjs-query
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -0,1 +1,7 @@ | ||
# 0.0.4 -- promises, louder errors, more tests | ||
1. added promises | ||
2. louder errors | ||
3. more test coverage | ||
# 0.0.3 -- options with debug logging and other features | ||
@@ -2,0 +8,0 @@ |
{ | ||
"name": "ethjs-query", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "A simple query layer for the Ethereum RPC.", | ||
@@ -15,7 +15,8 @@ "main": "./src/index.js", | ||
"lint:staged": "lint-staged", | ||
"coveralls": "cat ./coverage/lcov/lcov.info | coveralls" | ||
"test-travis": "node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- src/tests/**/*.js -R spec --timeout 2000000", | ||
"coveralls": "npm run test-travis && cat ./coverage/lcov.info | coveralls" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+ssh://git@github.com/silentcicero/ethjs-query.git" | ||
"url": "git+ssh://git@github.com/ethjs/ethjs-query.git" | ||
}, | ||
@@ -35,8 +36,8 @@ "keywords": [ | ||
"bugs": { | ||
"url": "https://github.com/silentcicero/ethjs-query/issues" | ||
"url": "https://github.com/ethjs/ethjs-query/issues" | ||
}, | ||
"homepage": "https://github.com/silentcicero/ethjs-query#readme", | ||
"homepage": "https://github.com/ethjs/ethjs-query#readme", | ||
"dependencies": { | ||
"eth-query": "2.1.0", | ||
"ethjs-format": "0.0.6" | ||
"ethjs-format": "0.0.9" | ||
}, | ||
@@ -48,2 +49,3 @@ "devDependencies": { | ||
"eslint": "2.10.1", | ||
"istanbul": "0.4.5", | ||
"eslint-config-airbnb": "9.0.1", | ||
@@ -54,3 +56,3 @@ "eslint-import-resolver-webpack": "0.2.4", | ||
"eslint-plugin-react": "5.1.1", | ||
"ethereumjs-testrpc": "^3.0.2", | ||
"ethereumjs-testrpc": "3.0.2", | ||
"ethjs-abi": "0.0.1", | ||
@@ -57,0 +59,0 @@ "ethjs-util": "0.0.1", |
@@ -5,4 +5,4 @@ ## ethjs-query | ||
<!-- Dependency Status --> | ||
<a href="https://david-dm.org/SilentCicero/ethjs-query"> | ||
<img src="https://david-dm.org/SilentCicero/ethjs-query.svg" | ||
<a href="https://david-dm.org/ethjs/ethjs-query"> | ||
<img src="https://david-dm.org/ethjs/ethjs-query.svg" | ||
alt="Dependency Status" /> | ||
@@ -12,9 +12,9 @@ </a> | ||
<!-- devDependency Status --> | ||
<a href="https://david-dm.org/SilentCicero/ethjs-query#info=devDependencies"> | ||
<img src="https://david-dm.org/SilentCicero/ethjs-query/dev-status.svg" alt="devDependency Status" /> | ||
<a href="https://david-dm.org/ethjs/ethjs-query#info=devDependencies"> | ||
<img src="https://david-dm.org/ethjs/ethjs-query/dev-status.svg" alt="devDependency Status" /> | ||
</a> | ||
<!-- Build Status --> | ||
<a href="https://travis-ci.org/SilentCicero/ethjs-query"> | ||
<img src="https://travis-ci.org/SilentCicero/ethjs-query.svg" | ||
<a href="https://travis-ci.org/ethjs/ethjs-query"> | ||
<img src="https://travis-ci.org/ethjs/ethjs-query.svg" | ||
alt="Build Status" /> | ||
@@ -29,2 +29,7 @@ </a> | ||
<!-- Test Coverage --> | ||
<a href="https://coveralls.io/r/ethjs/ethjs-query"> | ||
<img src="https://coveralls.io/repos/github/ethjs/ethjs-query/badge.svg" alt="Test Coverage" /> | ||
</a> | ||
<!-- Javascript Style --> | ||
@@ -61,3 +66,3 @@ <a href="http://airbnb.io/javascript/"> | ||
data: '0x', | ||
}, cb); | ||
}).then(cb).catch(cb); | ||
@@ -167,3 +172,3 @@ // result null 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 | ||
We communicate via [issues](https://github.com/SilentCicero/ethjs-query/issues) and [pull requests](https://github.com/SilentCicero/ethjs-query/pulls). | ||
We communicate via [issues](https://github.com/ethjs/ethjs-query/issues) and [pull requests](https://github.com/ethjs/ethjs-query/pulls). | ||
@@ -174,3 +179,3 @@ ## Important documents | ||
- [Code of Conduct](CODE_OF_CONDUCT.md) | ||
- [License](https://raw.githubusercontent.com/SilentCicero/ethjs-query/master/LICENSE) | ||
- [License](https://raw.githubusercontent.com/ethjs/ethjs-query/master/LICENSE) | ||
@@ -177,0 +182,0 @@ ## Licence |
132
src/index.js
@@ -6,3 +6,10 @@ const Query = require('eth-query'); | ||
function log(debug, logger, message) { | ||
if (debug) logger.log(`[ethjs-query ${(new Date()).toISOString()}] ${message}`); | ||
} | ||
function Eth(provider, options) { | ||
if (!(this instanceof Eth)) { throw new Error('the Eth object requires the "new" flag in order to function normally (i.e. `const eth = new Eth(provider);`).'); } | ||
if (typeof provider !== 'object') { throw new Error(`the Eth object requires that the first input 'provider' must be an object, got '${typeof provider}' (i.e. 'const eth = new Eth(provider);')`); } | ||
const self = this; | ||
@@ -19,46 +26,9 @@ const optionsObject = options || {}; | ||
Eth.prototype.getBalance = generateFnFor(2, 'eth_getBalance'); | ||
Eth.prototype.getCode = generateFnFor(2, 'eth_getCode'); | ||
Eth.prototype.getTransactionCount = generateFnFor(2, 'eth_getTransactionCount'); | ||
Eth.prototype.getStorageAt = generateFnFor(3, 'eth_getStorageAt'); | ||
Eth.prototype.call = generateFnFor(2, 'eth_call'); | ||
// standard | ||
Eth.prototype.protocolVersion = generateFnFor(1, 'eth_protocolVersion'); | ||
Eth.prototype.syncing = generateFnFor(1, 'eth_syncing'); | ||
Eth.prototype.coinbase = generateFnFor(1, 'eth_coinbase'); | ||
Eth.prototype.mining = generateFnFor(1, 'eth_mining'); | ||
Eth.prototype.hashrate = generateFnFor(1, 'eth_hashrate'); | ||
Eth.prototype.gasPrice = generateFnFor(1, 'eth_gasPrice'); | ||
Eth.prototype.accounts = generateFnFor(1, 'eth_accounts'); | ||
Eth.prototype.blockNumber = generateFnFor(1, 'eth_blockNumber'); | ||
Eth.prototype.getBlockTransactionCountByHash = generateFnFor(1, 'eth_getBlockTransactionCountByHash'); | ||
Eth.prototype.getBlockTransactionCountByNumber = generateFnFor(1, 'eth_getBlockTransactionCountByNumber'); | ||
Eth.prototype.getUncleCountByBlockHash = generateFnFor(1, 'eth_getUncleCountByBlockHash'); | ||
Eth.prototype.getUncleCountByBlockNumber = generateFnFor(1, 'eth_getUncleCountByBlockNumber'); | ||
Eth.prototype.sign = generateFnFor(1, 'eth_sign'); | ||
Eth.prototype.sendTransaction = generateFnFor(1, 'eth_sendTransaction'); | ||
Eth.prototype.sendRawTransaction = generateFnFor(1, 'eth_sendRawTransaction'); | ||
Eth.prototype.estimateGas = generateFnFor(1, 'eth_estimateGas'); | ||
Eth.prototype.getBlockByHash = generateFnFor(1, 'eth_getBlockByHash'); | ||
Eth.prototype.getBlockByNumber = generateFnFor(1, 'eth_getBlockByNumber'); | ||
Eth.prototype.getTransactionByHash = generateFnFor(1, 'eth_getTransactionByHash'); | ||
Eth.prototype.getTransactionByBlockHashAndIndex = generateFnFor(1, 'eth_getTransactionByBlockHashAndIndex'); | ||
Eth.prototype.getTransactionByBlockNumberAndIndex = generateFnFor(1, 'eth_getTransactionByBlockNumberAndIndex'); | ||
Eth.prototype.getTransactionReceipt = generateFnFor(1, 'eth_getTransactionReceipt'); | ||
Eth.prototype.getUncleByBlockHashAndIndex = generateFnFor(1, 'eth_getUncleByBlockHashAndIndex'); | ||
Eth.prototype.getUncleByBlockNumberAndIndex = generateFnFor(1, 'eth_getUncleByBlockNumberAndIndex'); | ||
Eth.prototype.getCompilers = generateFnFor(1, 'eth_getCompilers'); | ||
Eth.prototype.compileLLL = generateFnFor(1, 'eth_compileLLL'); | ||
Eth.prototype.compileSolidity = generateFnFor(1, 'eth_compileSolidity'); | ||
Eth.prototype.compileSerpent = generateFnFor(1, 'eth_compileSerpent'); | ||
Eth.prototype.newFilter = generateFnFor(1, 'eth_newFilter'); | ||
Eth.prototype.newBlockFilter = generateFnFor(1, 'eth_newBlockFilter'); | ||
Eth.prototype.newPendingTransactionFilter = generateFnFor(1, 'eth_newPendingTransactionFilter'); | ||
Eth.prototype.uninstallFilter = generateFnFor(1, 'eth_uninstallFilter'); | ||
Eth.prototype.getFilterChanges = generateFnFor(1, 'eth_getFilterChanges'); | ||
Eth.prototype.getFilterLogs = generateFnFor(1, 'eth_getFilterLogs'); | ||
Eth.prototype.getLogs = generateFnFor(1, 'eth_getLogs'); | ||
Eth.prototype.getWork = generateFnFor(1, 'eth_getWork'); | ||
Eth.prototype.submitWork = generateFnFor(1, 'eth_submitWork'); | ||
Eth.prototype.submitHashrate = generateFnFor(1, 'eth_submitHashrate'); | ||
Object.keys(format.schema.methods).forEach((rpcMethodName) => { | ||
const methodObject = format.schema.methods[rpcMethodName]; | ||
Object.defineProperty(Eth.prototype, rpcMethodName.replace('eth_', ''), { | ||
enumerable: true, | ||
value: generateFnFor(methodObject[3] || 1, rpcMethodName), // eslint-disable-line | ||
}); | ||
}); | ||
@@ -71,62 +41,60 @@ Eth.prototype.makeQuery = function (method, args) { // eslint-disable-line | ||
Eth.prototype.log = function log(message) { | ||
const self = this; | ||
if (self.options.debug === true) { | ||
const logMessage = `[ethjs-query ${(new Date()).toISOString()}] ${message}`; | ||
self.options.logger.log(logMessage); | ||
} | ||
}; | ||
Eth.prototype.stringify = function log(object) { | ||
const self = this; | ||
return JSON.stringify(object, null, self.options.jsonSpace); | ||
}; | ||
function generateFnFor(length, method) { | ||
function outputMethod() { | ||
var cb = (e, r) => {}; // eslint-disable-line | ||
const self = this; | ||
const debug = self.options.debug; | ||
const logger = self.options.logger; | ||
const minimumArgs = Number(format.schema.methods[method][2]); | ||
const maximumArgs = format.schema.methods[method][0].length; | ||
const args = [].slice.call(arguments); // eslint-disable-line | ||
const queryMethod = method.replace('eth_', ''); // eslint-disable-line | ||
self.log(`attempting method ${queryMethod} with params ${self.stringify(args)}`); | ||
log(debug, logger, `attempting method ${queryMethod} with params ${JSON.stringify(args, self.options.jsonSpace)}`); | ||
const cb = args.pop(); | ||
// if there is a callback, pop it out | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
log(debug, logger, `[method '${queryMethod}'] callback provided: true`); | ||
} | ||
self.log(`[method '${queryMethod}'] callback provided: ${typeof cb === 'function'}`); | ||
self.log(`[method '${queryMethod}'] attempting input formatting of ${args.length} inputs`); | ||
if (args.length < minimumArgs) { | ||
throw new Error(`method '${queryMethod}' requires at least ${minimumArgs} input (format type ${format.schema.methods[method][0][0]}), ${args.length} provided. For more information visit: https://github.com/ethereum/wiki/wiki/JSON-RPC#${method.toLowerCase()}`); | ||
} | ||
if (args.length > maximumArgs) { | ||
throw new Error(`method '${queryMethod}' requires at most ${maximumArgs} params, ${args.length} provided '${JSON.stringify(args)}'. For more information visit: https://github.com/ethereum/wiki/wiki/JSON-RPC#${method.toLowerCase()}`); | ||
} | ||
log(debug, logger, `[method '${queryMethod}'] attempting input formatting of ${args.length} inputs`); | ||
const inputs = format.formatInputs(method, args); | ||
self.log(`[method '${queryMethod}'] formatted inputs: ${self.stringify(inputs)}`); | ||
log(debug, logger, `[method '${queryMethod}'] formatted inputs: ${JSON.stringify(inputs, self.options.jsonSpace)}`); | ||
const callback = function(error, result) { // eslint-disable-line | ||
if (error) { | ||
cb(error, result); | ||
} else { | ||
self.log(`[method '${queryMethod}'] callback success, attempting formatting of raw outputs: ${self.stringify(result)}`); | ||
const output = new Promise((resolve, reject) => { | ||
const callback = function(error, result) { // eslint-disable-line | ||
if (error) { | ||
reject(error); | ||
cb(error, result); | ||
} else { | ||
log(debug, logger, `[method '${queryMethod}'] callback success, attempting formatting of raw outputs: ${JSON.stringify(result, self.options.jsonSpace)}`); | ||
try { | ||
const methodOutputs = format.formatOutputs(method, result); | ||
self.log(`[method '${queryMethod}'] formatted outputs: ${self.stringify(methodOutputs)}`); | ||
log(debug, logger, `[method '${queryMethod}'] formatted outputs: ${JSON.stringify(methodOutputs, self.options.jsonSpace)}`); | ||
resolve(methodOutputs); | ||
cb(null, methodOutputs); | ||
} catch (formatError) { | ||
cb(`error while formatting data from the RPC: ${formatError}`, null); | ||
} | ||
} | ||
}; | ||
}; | ||
inputs.push(callback); | ||
inputs.push(callback); | ||
try { | ||
self.log(`[method '${queryMethod}'] attempting query with formatted inputs...`); | ||
log(debug, logger, `[method '${queryMethod}'] attempting query with formatted inputs...`); | ||
self.makeQuery(queryMethod, inputs); | ||
} catch (queryError) { | ||
cb(`error while querying the RPC provider: ${queryError}`, null); | ||
} | ||
}); | ||
return output; | ||
} | ||
@@ -133,0 +101,0 @@ |
const Eth = require('../index.js'); // eslint-disable-line | ||
const Eth2 = require('../index.js'); // eslint-disable-line | ||
const assert = require('chai').assert; // eslint-disable-line | ||
@@ -23,3 +24,47 @@ const util = require('ethjs-util'); | ||
it('should check if the rpc is eth_syncing', () => { | ||
it('should construct normally with non Eth name', () => { | ||
const eth = new Eth2(provider); | ||
assert.equal(typeof eth, 'object'); | ||
assert.equal(typeof eth.query, 'object'); | ||
assert.equal(typeof eth.accounts, 'function'); | ||
assert.equal(typeof eth.getBalance, 'function'); | ||
assert.equal(typeof eth.sendTransaction, 'function'); | ||
assert.equal(typeof eth.sendRawTransaction, 'function'); | ||
}); | ||
it('should fail when no new flag is present', (done) => { | ||
try { | ||
const eth = Eth2(provider); // eslint-disable-line | ||
} catch (error) { | ||
assert.equal(typeof error, 'object'); | ||
done(); | ||
} | ||
}); | ||
it('should fail nicely when no first param on getBalance', (done) => { | ||
try { | ||
const eth = new Eth(provider); // eslint-disable-line | ||
eth.getBalance(); | ||
} catch (error) { | ||
assert.equal(typeof error, 'object'); | ||
} | ||
done(); | ||
}); | ||
it('should fail nicely when too many paramsEncoded on getBalance', (done) => { | ||
try { | ||
const eth = new Eth(provider); // eslint-disable-line | ||
eth.getBalance('fsdfsd', 'sdffsd', 'dsfdfssf'); | ||
} catch (error) { | ||
assert.equal(typeof error, 'object'); | ||
} | ||
done(); | ||
}); | ||
it('should check if the rpc is eth_syncing', (done) => { | ||
const eth = new Eth(provider); | ||
@@ -30,6 +75,8 @@ | ||
assert.equal(typeof result, 'boolean'); | ||
done(); | ||
}); | ||
}); | ||
it('should function while eth_coinbase', () => { | ||
it('should function while eth_coinbase', (done) => { | ||
const eth = new Eth(provider); | ||
@@ -41,5 +88,68 @@ | ||
assert.equal(util.getBinarySize(result), 42); | ||
done(); | ||
}); | ||
}); | ||
it('should function while eth_coinbase using promise', (done) => { | ||
const eth = new Eth(provider); | ||
eth.coinbase() | ||
.then((result) => { | ||
assert.equal(typeof result, 'string'); | ||
assert.equal(util.getBinarySize(result), 42); | ||
done(); | ||
}) | ||
.catch((err) => { | ||
assert.equal(err, null); | ||
}); | ||
}); | ||
it('should function while eth_getBalance using promise', (done) => { | ||
const eth = new Eth(provider); | ||
eth.coinbase() | ||
.then((result) => { | ||
assert.equal(typeof result, 'string'); | ||
assert.equal(util.getBinarySize(result), 42); | ||
eth.getBalance(result) | ||
.then((balance) => { | ||
assert.equal(typeof balance, 'object'); | ||
done(); | ||
}) | ||
.catch((err) => { | ||
assert.equal(err, null); | ||
}); | ||
}) | ||
.catch((err) => { | ||
assert.equal(err, null); | ||
}); | ||
}); | ||
it('should function while eth_getBalance, optional and non optional latest', (done) => { | ||
const eth = new Eth(provider); | ||
eth.coinbase((err, coinbase) => { | ||
assert.equal(err, null); | ||
assert.equal(typeof coinbase, 'string'); | ||
assert.equal(util.getBinarySize(coinbase), 42); | ||
eth.getBalance(coinbase, (balanceError, balance) => { | ||
assert.equal(balanceError, null); | ||
assert.equal(typeof balance, 'object'); | ||
eth.getBalance(coinbase, 'latest', (balanceLatestError, balanceLatest) => { | ||
assert.equal(balanceLatestError, null); | ||
assert.equal(typeof balanceLatest, 'object'); | ||
assert.equal(balance.toNumber(10), balanceLatest.toNumber(10)); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('should function while get_accounts', (done) => { | ||
@@ -55,2 +165,3 @@ const eth = new Eth(provider); | ||
assert.equal(util.getBinarySize(result[0]), 42); | ||
done(); | ||
@@ -57,0 +168,0 @@ }); |
Sorry, the diff of this file is not supported yet
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
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
52773
14
642
203
16
+ Addedethjs-filter@0.0.1(transitive)
+ Addedethjs-format@0.0.9(transitive)
+ Addedethjs-util@0.0.3(transitive)
- Removedethjs-format@0.0.6(transitive)
- Removedethjs-util@0.0.1(transitive)
Updatedethjs-format@0.0.9